Processamento de dados
#Estados
sipni_cobertura_uf_1994_2023_2 = sipni_cobertura_uf_1994_2023 %>%
mutate(mun_uf = "UF",
nome = uf,
nome = toupper(nome),
nome = stri_trans_general(nome, "Latin-ASCII")) %>%
select(nome, uf, ano, imuno, cobertura, mun_uf)
saveRDS(sipni_cobertura_uf_1994_2023_2, file = "sipni_cobertura_uf_1994_2023_2.rds")
#Municípios
sipni_cobertura_municipios_1994_2023_2 = sipni_cobertura_municipios_1994_2023 %>%
mutate(codigo = as.character(str_extract(municipio, "\\d+")),# Extrair números
nome = str_remove(municipio, "\\d+ "),# Extrair texto
mun_uf = "Município" ) %>%
select(!"...1":municipio)
glimpse(sipni_cobertura_municipios_1994_2023_2)
# #Unir
# sipni_all = bind_rows(sipni_cobertura_uf_1994_2023_2, sipni_cobertura_municipios_1994_2023_2)
# write.csv(sipni_all, file = "sipni_uf_mun_1994_2023.csv")
#Anotar municipios e estados
#Anotações de cidades. Fonte: IBGE. https://www.ibge.gov.br/explica/codigos-dos-municipios.php
dtb_municipios_cod = RELATORIO_DTB_BRASIL_MUNICIPIO %>%
clean_names() %>%
select(codigo_uf = uf, uf = nome_uf, codigo = codigo_municipio_completo, nome_municipio) %>%
mutate(nome_municipio_original = nome_municipio,
nome = toupper(nome_municipio_original),
nome = stri_trans_general(nome, "Latin-ASCII")) %>%
select(-nome_municipio)
municipios = sipni_cobertura_municipios_1994_2023_2 %>%
mutate(nome = gsub("\\\\", "", nome)) %>%
left_join(dtb_municipios_cod, by = "nome") %>%
select(nome, nome_municipio_original, uf, codigo_municipio = codigo.y, ano, imuno, cobertura, codigo_uf, mun_uf)
#Salvar
saveRDS(municipios, file = "sipni_cobertura_municipios_1994_2023_2.rds")
#Análise de dados Os dados das populações foram obtidos dos anos 2000
a 2022, pois os anos 2007 e 2023 não estavam disponíveis. Definir
variáveis - https://www.ibge.gov.br/estatisticas/downloads-estatisticas.html
- Censos - Perfil Estados - Perfil Municipios - Economicos - Indicadores
sociais - Educacação e qualificação profissional - Economia de saúde -
Acesso à internet - Educação - Saúde
install.packages("basedosdados")
library("basedosdados")
# Para carregar o dado direto no R
query <- bdplyr("br_ibge_censo_demografico.microdados_domicilio_1970")
df <- bd_collect(query)
install.packages("bdplyr")
query <- bdplyr("br_ms_atencao_basica.municipio")
df <- bd_collect(query)
# População ----
# Obter população de municipios.
anos = 2000:2023
resultados = list()
for (ano in anos) {
tryCatch({
# Chamar a função populacao_municipios para o ano atual e armazenar o resultado na lista
df_ano <- populacao_municipios(ano)
df_ano <- df_ano %>%
mutate_all(as.character) # Convertendo todas as colunas para character
resultados[[as.character(ano)]] <- df_ano
}, error = function(e) {
# Tratar o erro (por exemplo, imprimir uma mensagem)
print(paste("Erro para o ano", ano, ":", conditionMessage(e)))
})
}
# Combinar todos os dataframes em um único dataframe
populacao_municipios_2000_2022 <- bind_rows(resultados, .id = "ano") %>%
select(uf_abrev = uf,
nome_municipio_original = nome_munic,
ano, codigo_uf,
populacao,
codigo_municipio = cod_municipio) %>%
mutate(ano = as.numeric(ano),
populacao = as.numeric(populacao))
print(populacao_municipios_2000_2022)
# GDP ----
anos = 1999:2020
pib_municipios(ano = 2003)
resultados = list()
for (ano in anos) {
tryCatch({
df_ano <- pib_municipios(ano = ano, dir=".")
resultados[[ano]] <- df_ano
}, error = function(e) {
print(paste("Erro para o ano", ano, ":", conditionMessage(e)))
})
}
# Combinar todos os dataframes em um único dataframe
populacao_municipios_2000_2022 <- bind_rows(resultados, .id = "ano") %>%
select(uf_abrev = uf,
nome_municipio_original = nome_munic,
ano, codigo_uf,
populacao,
codigo_municipio = cod_municipio) %>%
mutate(ano = as.numeric(ano),
populacao = as.numeric(populacao))
print(populacao_municipios_2000_2022)
#Unir dados
municipios_2 = municipios %>%
left_join(populacao_municipios_2000_2022 %>%
select(codigo_municipio, ano, populacao),
by = c("codigo_municipio", "ano"))
#IEPS dados
#Unir dados
IEPS_Brasil_2010_2022_Todos <- read_excel("dados_brutos/IEPS/IEPS_Brasil_2010_2022_Todos.xlsx") %>%
mutate(nivel = "Brasil")
IEPS_Estados_2010_2022_Todos <- read_excel("dados_brutos/IEPS/IEPS_Estados_2010_2022_Todos.xlsx") %>%
mutate(nivel = "Estado")
IEPS_MacroRegiao_2010_2022_Todos <- read_excel("dados_brutos/IEPS/IEPS_MacroRegiao_2010_2022_Todos.xlsx") %>%
mutate(nivel = "Macro Região")
IEPS_Municipios_2010_2022_Todos <- read_excel("dados_brutos/IEPS/IEPS_Municipios_2010_2022_Todos.xlsx") %>%
mutate(nivel = "Município")
IEPS_Regiao_2010_2022_Todos <- read_excel("dados_brutos/IEPS/IEPS_Regiao_2010_2022_Todos.xlsx") %>%
mutate(nivel = "Região")
IEPS_Completo_2010_2022_Todos = bind_rows(IEPS_Brasil_2010_2022_Todos,
IEPS_Estados_2010_2022_Todos,
IEPS_MacroRegiao_2010_2022_Todos,
IEPS_Regiao_2010_2022_Todos,
IEPS_Municipios_2010_2022_Todos)
#Padronizar tabelas
IEPS_Brasil_2010_2022_Todos <- IEPS_Brasil_2010_2022_Todos %>%
mutate(nivel = "Brasil") %>%
mutate(across(c(cob_ab:pct_pop_masc), ~ str_replace(., ",", "."))) %>%
mutate(across(c(cob_ab:pct_pop_masc), ~ as.numeric(.))) %>%
mutate(ano = lubridate::ymd(ano, truncated = 2L))
IEPS_Estados_2010_2022_Todos <- IEPS_Estados_2010_2022_Todos %>%
mutate(nivel = "Estado") %>%
mutate(across(c(cob_ab:pct_pop_masc), ~ str_replace(., ",", "."))) %>%
mutate(across(c(cob_ab:pct_pop_masc), ~ as.numeric(.))) %>%
mutate(ano = lubridate::ymd(ano, truncated = 2L))
IEPS_MacroRegiao_2010_2022_Todos <- IEPS_MacroRegiao_2010_2022_Todos %>%
mutate(nivel = "Macro Região") %>%
mutate(across(c(cob_ab:pct_pop_masc), ~ str_replace(., ",", "."))) %>%
mutate(across(c(cob_ab:pct_pop_masc), ~ as.numeric(.))) %>%
mutate(ano = lubridate::ymd(ano, truncated = 2L))
IEPS_Regiao_2010_2022_Todos <- IEPS_Regiao_2010_2022_Todos %>%
mutate(nivel = "Região") %>%
mutate(across(c(cob_ab:pct_pop_masc), ~ str_replace(., ",", "."))) %>%
mutate(across(c(cob_ab:pct_pop_masc), ~ as.numeric(.))) %>%
mutate(ano = lubridate::ymd(ano, truncated = 2L))
IEPS_Municipios_2010_2022_Todos <- IEPS_Municipios_2010_2022_Todos %>%
mutate(nivel = "Município",
porte_municipio = case_when(pop <= 20000 ~ "Município de Pequeno Porte I",
pop <= 50000 ~ "Município de Pequeno Porte II",
pop <= 100000 ~ "Município de Médio Porte",
pop <= 900000 ~ "Município de Grande Porte",
TRUE ~ "Metrópole")) %>%
mutate(across(c(cob_ab:pct_pop_masc), ~ str_replace(., ",", "."))) %>%
mutate(across(c(cob_ab:pct_pop_masc), ~ as.numeric(.))) %>%
mutate(ano = lubridate::ymd(ano, truncated = 2L))
IEPS_Completo_2010_2022_Todos = IEPS_Completo_2010_2022_Todos %>%
mutate(across(c(cob_ab:pct_pop_masc), ~ str_replace(., ",", "."))) %>%
mutate(across(c(cob_ab:pct_pop_masc), ~ as.numeric(.))) %>%
mutate(ano = lubridate::ymd(ano, truncated = 2L))
IEPS_Completo_2010_2022_Todos %>%
saveRDS(file = here("dados_processados", "IEPS_Completo_2010_2022_Todos.rds"))
Seleção de variáveis
#Análise exploratória
#Definir tema
ggthemr("fresh", spacing = 1)
Brasil

São Paulo
#Importar dados
IEPS_Completo_2010_2022_selecionados_SP <- readRDS(here("dados_processados", "IEPS_Completo_2010_2022_selecionados_SP.rds"))
IEPS_var_selecionadas = read_excel("dados_processados/IEPS_codebook_selecionados.xlsx") %>%
clean_names() %>%
filter(selecao == "Sim") %>%
mutate(bloco = if_else(str_detect(variavel, "cob_vac"), "Cobertura vacinal", bloco))
#Manipulação
IEPS_Completo_filtrado_SP = IEPS_Completo_2010_2022_selecionados_SP %>%
filter(nivel == "Estado") %>%
pivot_longer(cols = cob_ab:pct_pop_masc,
names_to = "variavel",
values_to = "valor") %>%
inner_join(IEPS_var_selecionadas, by = "variavel") %>%
mutate(ano = lubridate::ymd(ano, truncated = 2L))
IEPS_Completo_Regiao_SP = IEPS_Completo_2010_2022_selecionados_SP %>%
filter(nivel == "Região") %>%
pivot_longer(cols = cob_ab:pct_pop_masc,
names_to = "variavel",
values_to = "valor") %>%
inner_join(IEPS_var_selecionadas, by = "variavel") %>%
mutate(ano = lubridate::ymd(ano, truncated = 2L))
IEPS_Completo_Municipio_SP = IEPS_Completo_2010_2022_selecionados_SP %>%
filter(nivel == "Município") %>%
pivot_longer(cols = cob_ab:pct_pop_masc,
names_to = "variavel",
values_to = "valor") %>%
inner_join(IEPS_var_selecionadas, by = "variavel") %>%
mutate(ano = lubridate::ymd(ano, truncated = 2L))
IEPS_Completo_Regiao_SP_vacinas = IEPS_Completo_Regiao_SP %>%
filter(str_detect(nome_dos_indicadores, "Cobertura Vacinal")) %>%
select(ano, regiao, no_regiao, nome_dos_indicadores, valor) %>%
mutate(valor = round(valor, 2),
ano = as.character(ano) %>% str_replace(., "-01-01", ""),
nome_dos_indicadores = str_replace(nome_dos_indicadores, "Cobertura Vacinal de ", ""),
nome_dos_indicadores = str_replace(nome_dos_indicadores, " \\(\\%\\)", ""))
IEPS_Completo_Municipio_SP_vacinas = IEPS_Completo_Municipio_SP %>%
filter(str_detect(nome_dos_indicadores, "Cobertura Vacinal")) %>%
select(ano, regiao, nomemun, nome_dos_indicadores, valor) %>%
mutate(valor = round(valor, 2),
ano = as.character(ano) %>% str_replace(., "-01-01", ""),
nome_dos_indicadores = str_replace(nome_dos_indicadores, "Cobertura Vacinal de ", ""),
nome_dos_indicadores = str_replace(nome_dos_indicadores, " \\(\\%\\)", ""))
Quais regiões tiveram cobertura vacinal mínima de 90% entre 2015 e
2022? Isto é, quais regiões foram menos afetadas pelo efeito 2016 e pela
pandemia?
#Regiões -----
dados_vacinas = IEPS_Completo_Regiao_SP %>%
filter(str_detect(nome_dos_indicadores, "Cobertura Vacinal")) %>%
select(ano, regiao, no_regiao, nome_dos_indicadores, valor) %>%
mutate(valor = round(valor, 2),
nome_dos_indicadores = str_replace(nome_dos_indicadores, "Cobertura Vacinal de ", ""),
nome_dos_indicadores = str_replace(nome_dos_indicadores, " \\(\\%\\)", "")) %>%
drop_na()
#Selecionar regiões com cobertura vacinal mínima de 90%
regioes_acima_90 = dados_vacinas %>%
filter(ano >= ymd("2015-01-01") & ano <= ymd("2022-01-01")) %>%
group_by(no_regiao, nome_dos_indicadores) %>%
summarise(min_coverage = min(valor)) %>%
filter(min_coverage > 90)
#Municípios ------
dados_vacinas = IEPS_Completo_Municipio_SP %>%
filter(str_detect(nome_dos_indicadores, "Cobertura Vacinal")) %>%
select(ano, regiao, nomemun, nome_dos_indicadores, valor) %>%
mutate(valor = round(valor, 2),
nome_dos_indicadores = str_replace(nome_dos_indicadores, "Cobertura Vacinal de ", ""),
nome_dos_indicadores = str_replace(nome_dos_indicadores, " \\(\\%\\)", "")) %>%
drop_na()
#Selecionar municipios com cobertura vacinal mínima de 90%
municipios_acima_90 = dados_vacinas %>%
filter(ano >= ymd("2015-01-01") & ano <= ymd("2022-01-01")) %>%
group_by(nomemun, nome_dos_indicadores) %>%
summarise(min_coverage = min(valor)) %>%
filter(min_coverage > 90)
Quais foram as regiões que mais tiveram redução da cobertura vacinal
por vacina?
# Calcular a variação anual e filtrar variações negativas
variacoes_negativas <- dados_vacinas %>%
drop_na() %>%
arrange(no_regiao, nome_dos_indicadores, ano) %>%
group_by(no_regiao, nome_dos_indicadores) %>%
mutate(variacao_anual = valor - lag(valor)) %>%
group_by(nome_dos_indicadores) %>%
arrange(nome_dos_indicadores, variacao_anual) %>%
filter(variacao_anual<0)
#Top 5 regiões com maior queda da cobertura vacinal
variacoes_negativas_top5 = variacoes_negativas %>%
slice_min(n = 5, order_by = variacao_anual)
top5_reduz_2016 = variacoes_negativas %>%
filter(ano == "2016-01-01") %>%
slice_min(n = 5, order_by = variacao_anual)
top5_reduz_2020 = variacoes_negativas %>%
filter(ano == "2020-01-01") %>%
slice_min(n = 5, order_by = variacao_anual)
#Top 5 regiões com maior queda da cobertura de BCG
bcg_top5_reduz_2016 = variacoes_negativas %>%
filter(ano == "2016-01-01",
nome_dos_indicadores == "BCG") %>%
slice_min(n = 5, order_by = variacao_anual)
bcg_top5_reduz_2020 = variacoes_negativas %>%
filter(ano == "2020-01-01",
nome_dos_indicadores == "BCG") %>%
slice_min(n = 5, order_by = variacao_anual)
bcg_top5_reduz_2016
bcg_top5_reduz_2020
E os municípios?
# Calcular a variação anual e filtrar variações negativas
variacoes_negativas <- dados_vacinas %>%
drop_na() %>%
arrange(nomemun, nome_dos_indicadores, ano) %>%
group_by(nomemun, nome_dos_indicadores) %>%
mutate(variacao_anual = valor - lag(valor)) %>%
group_by(nome_dos_indicadores) %>%
arrange(nome_dos_indicadores, variacao_anual) %>%
filter(variacao_anual<0)
#Top 5 regiões com maior queda da cobertura vacinal
variacoes_negativas_top5_mun = variacoes_negativas %>%
slice_min(n = 5, order_by = variacao_anual)
top5_reduz_2016_mun = variacoes_negativas %>%
filter(ano == "2016-01-01") %>%
slice_min(n = 5, order_by = variacao_anual)
top5_reduz_2020_mun = variacoes_negativas %>%
filter(ano == "2020-01-01") %>%
slice_min(n = 5, order_by = variacao_anual)
#Top 5 regiões com maior queda da cobertura de BCG
bcg_top5_reduz_2016_mun = variacoes_negativas %>%
filter(ano == "2016-01-01",
nome_dos_indicadores == "BCG") %>%
slice_min(n = 5, order_by = variacao_anual)
bcg_top5_reduz_2020_mun = variacoes_negativas %>%
filter(ano == "2020-01-01",
nome_dos_indicadores == "BCG") %>%
slice_min(n = 5, order_by = variacao_anual)
bcg_top5_reduz_2016_mun
bcg_top5_reduz_2020_mun
vacinas_estado_sp = IEPS_Completo_filtrado_SP %>%
filter(bloco == "Cobertura vacinal") %>%
bind_rows(brasil_vacinas) %>%
mutate(nivel = if_else(nivel == "Estado", "São Paulo", nivel),
nome_dos_indicadores = str_replace(nome_dos_indicadores, "Cobertura Vacinal de ", ""),
nome_dos_indicadores = str_replace(nome_dos_indicadores, " \\(\\%\\)", ""),
nivel = fct_rev(nivel)) %>%
ggplot() +
aes(x = ano, y = valor, group = nivel) +
scale_x_date(date_breaks = "1 year", date_labels = "%y") +
scale_y_continuous(expand = expansion(add = 10)) +
geom_rect(xmin = as.numeric(as.Date("2016-01-01")),
xmax = as.numeric(as.Date("2020-01-01")),
ymin = 0,
ymax = 110,
fill = "gray",
alpha = 0.03) +
geom_rect(xmin = as.numeric(as.Date("2020-01-01")),
xmax = as.numeric(as.Date("2022-01-01")),
ymin = 0,
ymax = 110,
fill = "gray40",
alpha = 0.03) +
geom_line(size = 2, mapping = aes(color = nivel, linetype = nivel)) +
theme(text = element_text(size = 12),
plot.title = element_text(size = 20),
plot.subtitle = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
legend.position = "top",
strip.text.x = element_text(size = 12,
margin = margin(5, 5, 15, 5, "pt"))) +
labs(title = "Cobertura vacinal no estado de São Paulo",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
color = "",
y = "Cobertura vacinal (%)",
x = "") +
facet_wrap(~nome_dos_indicadores, scales = "free")
vacinas_estado_sp %>%
ggsave(file = here("Figuras", "Vacinas_Brasil_SP_2010_2022_linhas.png"), width = 12, height = 7)
vacinas_estado_sp

#Análise por microrregião
Densidade
IEPS_Completo_Regiao_SP_vacinas_ridge = IEPS_Completo_Regiao_SP_vacinas %>%
drop_na() %>%
ggplot() +
aes(x = valor, y = fct_rev(ano), fill = ano) +
geom_density_ridges() +
scale_fill_manual(values = colorRampPalette(c("#65ADC2", "purple"))(15)) +
theme(legend.position = "none",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
strip.text.x = element_text(size = 15, face = "bold"),
panel.spacing=unit(2, "lines")) +
labs(title = "Cobertura vacinal",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
y = "",
x = "Cobertura vacinal (%)") +
facet_wrap(~nome_dos_indicadores, scales = "free_x", nrow = 2)
IEPS_Completo_Regiao_SP_vacinas_ridge %>%
ggsave(file = here("Figuras", "vacinas_regioes_estado_sp_2010_2022_densidade.png"), width = 15, height = 10)
IEPS_Completo_Regiao_SP_vacinas_ridge
Boxplots
IEPS_Completo_Regiao_SP_vacinas_boxplot = IEPS_Completo_Regiao_SP_vacinas %>%
drop_na() %>%
ggplot() +
aes(x = valor, y = fct_rev(ano), fill = ano) +
geom_boxplot(outliers = F) +
geom_jitter(aes(label = no_regiao, color = valor),
alpha = 0.2,
na.rm = T) +
scale_fill_manual(values = colorRampPalette(c("#65ADC2", "purple"))(15)) +
facet_wrap(vars(nome_dos_indicadores)) +
theme(legend.position = "none",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
strip.text.x = element_text(size = 15, face = "bold"),
panel.spacing=unit(2, "lines")) +
labs(title = "Cobertura vacinal",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
y = "",
x = "Cobertura vacinal (%)") +
facet_wrap(~nome_dos_indicadores, scales = "free_x", nrow = 2)
IEPS_Completo_Regiao_SP_vacinas_boxplot %>%
ggsave(file = here("Figuras", "vacinas_regioes_estado_sp_2010_2022_boxplot.png"), width = 15, height = 12)
IEPS_Completo_Regiao_SP_vacinas_boxplot
IEPS_Completo_Regiao_SP_vacinas_BCG_boxplot = IEPS_Completo_Regiao_SP_vacinas %>%
filter(nome_dos_indicadores == "BCG") %>%
drop_na() %>%
ggplot() +
aes(x = fct_rev(ano), y = valor, fill = ano) +
geom_boxplot(outliers = F) +
geom_jitter(aes(label = no_regiao, color = valor),
alpha = 0.2,
na.rm = T) +
scale_fill_manual(values = colorRampPalette(c("#65ADC2", "purple"))(15)) +
theme(legend.position = "none",
text = element_text(size = 12, color = "black"),
plot.title = element_text(size = 20),
plot.subtitle = element_text(size = 15),
plot.caption = element_text(size = 10),
plot.margin = unit(c(1,1,1,1), "cm"),
strip.text.x = element_text(size = 10, face = "bold"),
panel.spacing=unit(2, "lines")) +
labs(title = "Cobertura vacinal - BCG",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
y = "",
x = "Cobertura vacinal (%)")
ggplotly(IEPS_Completo_Regiao_SP_vacinas_BCG_boxplot)
Gráfico de linhas
regioes_acima_90_vacina_linhas = IEPS_Completo_Regiao_SP %>%
filter(str_detect(nome_dos_indicadores, "Cobertura Vacinal"),
no_regiao %in% unique(regioes_acima_90$no_regiao)) %>%
select(ano, regiao, no_regiao, nome_dos_indicadores, valor) %>%
mutate(valor = round(valor, 2),
nome_dos_indicadores = str_replace(nome_dos_indicadores, "Cobertura Vacinal de ", ""),
nome_dos_indicadores = str_replace(nome_dos_indicadores, " \\(\\%\\)", "")) %>%
drop_na() %>%
ggplot() +
aes(x = ano, y = valor, group = no_regiao) +
geom_line(aes(color = no_regiao),
size = 2) +
scale_x_date(date_breaks = "1 year", date_labels = "%y") +
theme(legend.position = "top",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
legend.text = element_text(size = 15),
strip.text.x = element_text(size = 15, face = "plain")) +
labs(title = "Cobertura vacinal no estado de São Paulo",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
color = "Microrregião",
y = "Cobertura vacinal (%)",
x = "") +
facet_wrap(~nome_dos_indicadores, scales = "free") +
scale_shape_manual(values = c(16)) +
scale_color_cosmic()
regioes_acima_90_vacina_linhas
regioes_acima_90_vacina_linhas %>%
ggsave(file = here("Figuras", "vacinas_acima_90_regioes_estado_sp_2010_2022_linhas.png"), width = 15, height = 10)
bcg_queda_2016_linhas = IEPS_Completo_Regiao_SP %>%
filter(str_detect(nome_dos_indicadores, "Cobertura Vacinal"),
str_detect(nome_dos_indicadores, "BCG"),
no_regiao %in% bcg_top5_reduz_2016$no_regiao) %>%
select(ano, regiao, no_regiao, nome_dos_indicadores, valor) %>%
mutate(valor = round(valor, 2),
nome_dos_indicadores = str_replace(nome_dos_indicadores, "Cobertura Vacinal de ", ""),
nome_dos_indicadores = str_replace(nome_dos_indicadores, " \\(\\%\\)", "")) %>%
drop_na() %>%
ggplot() +
aes(x = ano, y = valor, group = no_regiao) +
geom_line(aes(color = no_regiao),
size = 2) +
scale_x_date(date_breaks = "1 year", date_labels = "%y") +
theme(legend.position = "right",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
legend.text = element_text(size = 15),
strip.text.x = element_text(size = 15, face = "plain")) +
labs(title = "Cobertura vacinal da BCG no estado de São Paulo",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
color = "Microrregião",
y = "Cobertura vacinal (%)",
x = "") +
scale_color_cosmic()
bcg_queda_2016_linhas
bcg_queda_2016_linhas %>%
ggsave(file = here("Figuras", "vacinas_queda_2016_regioes_estado_sp_2010_2022_linhas.png"), width = 10, height = 5)
2020
bcg_queda_2020_linhas = IEPS_Completo_Regiao_SP %>%
filter(str_detect(nome_dos_indicadores, "Cobertura Vacinal"),
str_detect(nome_dos_indicadores, "BCG"),
no_regiao %in% bcg_top5_reduz_2020$no_regiao) %>%
select(ano, regiao, no_regiao, nome_dos_indicadores, valor) %>%
mutate(valor = round(valor, 2),
nome_dos_indicadores = str_replace(nome_dos_indicadores, "Cobertura Vacinal de ", ""),
nome_dos_indicadores = str_replace(nome_dos_indicadores, " \\(\\%\\)", "")) %>%
drop_na() %>%
ggplot() +
aes(x = ano, y = valor, group = no_regiao) +
geom_line(aes(color = no_regiao),
size = 2) +
scale_x_date(date_breaks = "1 year", date_labels = "%y") +
theme(legend.position = "right",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
legend.text = element_text(size = 15),
strip.text.x = element_text(size = 15, face = "plain")) +
labs(title = "Cobertura vacinal da BCG no estado de São Paulo",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
color = "Microrregião",
y = "Cobertura vacinal (%)",
x = "") +
scale_color_cosmic()
bcg_queda_2020_linhas
bcg_queda_2020_linhas %>%
ggsave(file = here("Figuras", "vacinas_queda_2020_regioes_estado_sp_2010_2022_linhas.png"), width = 10, height = 5)
#Análise por municipio
Boxplots
IEPS_Completo_Municipio_SP_vacinas_boxplot = IEPS_Completo_Municipio_SP %>%
filter(str_detect(variavel, "cob_vac_")) %>%
drop_na() %>%
mutate(ano = as.character(ano)) %>%
ggplot() +
aes(x = valor, y = fct_rev(ano), fill = ano) +
geom_jitter(aes(label = no_regiao, color = valor),
alpha = 0.2,
na.rm = T) +
geom_boxplot(outliers = F) +
scale_fill_manual(values = colorRampPalette(c("#65ADC2", "purple"))(15)) +
theme(legend.position = "none",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
strip.text.x = element_text(size = 15, face = "bold"),
panel.spacing=unit(2, "lines")) +
labs(title = "Cobertura vacinal, por municipio",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
y = "",
x = "Cobertura vacinal (%)") +
facet_wrap(~nome_dos_indicadores, scales = "free_x", nrow = 2)
IEPS_Completo_Municipio_SP_vacinas_boxplot %>%
ggsave(file = here("Figuras", "Vacinas_Municipios_SP_2010_2022_boxplot.png"), width = 20, height = 12)
IEPS_Completo_Municipio_SP_vacinas_boxplot
Boxplot interativo
IEPS_Completo_Regiao_SP_vacinas_BCG_boxplot = IEPS_Completo_Regiao_SP_vacinas %>%
filter(nome_dos_indicadores == "BCG") %>%
drop_na() %>%
ggplot() +
aes(x = fct_rev(ano), y = valor, fill = ano) +
geom_boxplot(outliers = F) +
geom_jitter(aes(label = no_regiao, color = valor),
alpha = 0.2,
na.rm = T) +
scale_fill_manual(values = colorRampPalette(c("#65ADC2", "purple"))(15)) +
theme(legend.position = "none",
text = element_text(size = 12, color = "black"),
plot.title = element_text(size = 20),
plot.subtitle = element_text(size = 15),
plot.caption = element_text(size = 10),
plot.margin = unit(c(1,1,1,1), "cm"),
strip.text.x = element_text(size = 10, face = "bold"),
panel.spacing=unit(2, "lines")) +
labs(title = "Cobertura vacinal - BCG",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
y = "",
x = "Cobertura vacinal (%)")
ggplotly(IEPS_Completo_Regiao_SP_vacinas_BCG_boxplot)
Gráfico de linhas
regioes_acima_90_vacina_linhas = IEPS_Completo_Regiao_SP %>%
filter(str_detect(nome_dos_indicadores, "Cobertura Vacinal"),
no_regiao %in% unique(regioes_acima_90$no_regiao)) %>%
select(ano, regiao, no_regiao, nome_dos_indicadores, valor) %>%
mutate(valor = round(valor, 2),
nome_dos_indicadores = str_replace(nome_dos_indicadores, "Cobertura Vacinal de ", ""),
nome_dos_indicadores = str_replace(nome_dos_indicadores, " \\(\\%\\)", "")) %>%
drop_na() %>%
ggplot() +
aes(x = ano, y = valor, group = no_regiao) +
geom_line(aes(color = no_regiao),
size = 2) +
scale_x_date(date_breaks = "1 year", date_labels = "%y") +
theme(legend.position = "top",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
legend.text = element_text(size = 15),
strip.text.x = element_text(size = 15, face = "plain")) +
labs(title = "Cobertura vacinal no estado de São Paulo",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
color = "Microrregião",
y = "Cobertura vacinal (%)",
x = "") +
facet_wrap(~nome_dos_indicadores, scales = "free") +
scale_shape_manual(values = c(16)) +
scale_color_cosmic()
regioes_acima_90_vacina_linhas
regioes_acima_90_vacina_linhas %>%
ggsave(file = here("Figuras", "vacinas_acima_90_regioes_estado_sp_2010_2022_linhas.png"), width = 15, height = 10)
bcg_queda_2016_linhas = IEPS_Completo_Regiao_SP %>%
filter(str_detect(nome_dos_indicadores, "Cobertura Vacinal"),
str_detect(nome_dos_indicadores, "BCG"),
no_regiao %in% bcg_top5_reduz_2016$no_regiao) %>%
select(ano, regiao, no_regiao, nome_dos_indicadores, valor) %>%
mutate(valor = round(valor, 2),
nome_dos_indicadores = str_replace(nome_dos_indicadores, "Cobertura Vacinal de ", ""),
nome_dos_indicadores = str_replace(nome_dos_indicadores, " \\(\\%\\)", "")) %>%
drop_na() %>%
ggplot() +
aes(x = ano, y = valor, group = no_regiao) +
geom_line(aes(color = no_regiao),
size = 2) +
scale_x_date(date_breaks = "1 year", date_labels = "%y") +
theme(legend.position = "right",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
legend.text = element_text(size = 15),
strip.text.x = element_text(size = 15, face = "plain")) +
labs(title = "Cobertura vacinal da BCG no estado de São Paulo",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
color = "Microrregião",
y = "Cobertura vacinal (%)",
x = "") +
scale_color_cosmic()
bcg_queda_2016_linhas
bcg_queda_2016_linhas %>%
ggsave(file = here("Figuras", "vacinas_queda_2016_regioes_estado_sp_2010_2022_linhas.png"), width = 10, height = 5)
2020
bcg_queda_2020_linhas = IEPS_Completo_Regiao_SP %>%
filter(str_detect(nome_dos_indicadores, "Cobertura Vacinal"),
str_detect(nome_dos_indicadores, "BCG"),
no_regiao %in% bcg_top5_reduz_2020$no_regiao) %>%
select(ano, regiao, no_regiao, nome_dos_indicadores, valor) %>%
mutate(valor = round(valor, 2),
nome_dos_indicadores = str_replace(nome_dos_indicadores, "Cobertura Vacinal de ", ""),
nome_dos_indicadores = str_replace(nome_dos_indicadores, " \\(\\%\\)", "")) %>%
drop_na() %>%
ggplot() +
aes(x = ano, y = valor, group = no_regiao) +
geom_line(aes(color = no_regiao),
size = 2) +
scale_x_date(date_breaks = "1 year", date_labels = "%y") +
theme(legend.position = "right",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
legend.text = element_text(size = 15),
strip.text.x = element_text(size = 15, face = "plain")) +
labs(title = "Cobertura vacinal da BCG no estado de São Paulo",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
color = "Microrregião",
y = "Cobertura vacinal (%)",
x = "") +
scale_color_cosmic()
bcg_queda_2020_linhas
bcg_queda_2020_linhas %>%
ggsave(file = here("Figuras", "vacinas_queda_2020_regioes_estado_sp_2010_2022_linhas.png"), width = 10, height = 5)
Microrregião
library(tidyverse)
library(ggrepel) #load before factoextra
library(factoextra)
library(caret)
library(stats)
library(ggfortify)
library(ggplot2)
library(corrplot)
library(cowplot)
library(ggcorrplot)
library(ComplexHeatmap)
library(circlize)
library(ggExtra)
library(FactoMineR)
Microrregião: Selecionados
#Imputs
ano_selec = "2020"
ano_selec_ymd = ymd("2020-01-01")
row_names = "no_regiao"
nivel_selec = "Região"
#
pca_dados = IEPS_Completo_2010_2022_selecionados_SP %>%
filter(nivel == nivel_selec,
ano == ano_selec) %>%
column_to_rownames(row_names) %>%
select(cob_ab:cob_vac_penta,
tx_mort_aj_cens:pct_desp_recp_saude_mun,
desp_tot_saude_pc_mun_def,
desp_recp_saude_pc_mun_def,
ideb_5ano:pop,
pct_pop_fem:pct_pop_masc)
pca_dados_matrix = pca_dados %>%
as.matrix()
dim(pca_dados_matrix)
pca_dados_ann = IEPS_Completo_2010_2022_selecionados_SP %>%
filter(nivel == nivel_selec,
ano == ano_selec) %>%
select(row_names, pop) %>%
mutate(porte_municipio = case_when(pop <= 20000 ~ "Pequeno Porte I",
pop <= 50000 ~ "Pequeno Porte II",
pop <= 100000 ~ "Médio Porte",
pop <= 900000 ~ "Grande Porte",
TRUE ~ "Metrópole"),
ID = row_names) %>%
select(-pop) %>%
column_to_rownames(row_names)
# Delete columns with near 0 variance
nearZeroVarCols <- nearZeroVar(pca_dados_matrix, saveMetrics = TRUE)
pca_dados_matrix_pca <- pca_dados_matrix[, !nearZeroVarCols$nzv]
pca_res <- prcomp(pca_dados_matrix_pca, scale. = T)
#Selecionar variáveis de interesse
corr_matrix_selec = corr_matrix %>%
as.data.frame() %>%
rownames_to_column("id") %>%
filter(str_detect(id, "cob_vac")) %>%
column_to_rownames("id") %>%
as.matrix()
# Correlation plot ----
corr_matrix = cor(pca_dados_matrix_pca %>% scale())
var <- get_pca_var(pca_res)
p.mat = cor_pmat(pca_dados_matrix_pca %>% scale())
p.mat_2 = cor_pmat(corr_matrix_selec %>% scale()) %>%
as.data.frame() %>%
rownames_to_column("id") %>%
inner_join(corr_matrix_selec %>% as.data.frame() %>% rownames_to_column("id") %>% select("id"), by = "id") %>%
column_to_rownames("id") %>%
as.matrix()
#Selecionados
png(file = here("Figuras", paste0("PCA_", nivel_selec ,"_", ano_selec, "_Selecionados_Corrplot.png")),
width = 15, height = 5,
units = "in",
res = 300)
corrplot(round(corr_matrix_selec, 2),
is.corr = TRUE,
tl.col = "black",
title = "Cobertura vacinal e indicadores sociais, economicos, demográficos e de saúde",
cex.main = 2,
method = "color",
p.mat = p.mat_2,
tl.srt = 45,
sig.level = c(0.05),
mar=c(1,0,4,0),
addCoef.col = 'black',
number.cex = 0.6,
insig = "blank",
col = colorRampPalette(c("#65ADC2", "white", "#E84646"))(11))
dev.off()
#Todos
corrplot = ggcorrplot(corr_matrix,
hc.order = TRUE,
method = "circle",
type = "full",
ggtheme = NULL,
outline.col = "white",
p.mat = p.mat,
insig = "blank",
sig.level = 0.05,
colors = c("#65ADC2", "white", "#E84646")) +
theme(axis.text.x = element_text(angle = 45, size = 10),
axis.text.y = element_text(size = 10)) +
labs(title = "Cobertura vacinal e indicadores sociais, economicos, demográficos e de saúde") +
theme(plot.title = element_text(size = 15, face = "bold"))
corrplot %>%
ggsave(file = here("Figuras", paste0("PCA_", nivel_selec ,"_", ano_selec, "_TodosIndicadores_Corrplot.png")), width = 15, height = 10)
#PCA ----
data.pca = prcomp(corr_matrix) #PCA
summary(corr_matrix) #Retornar PCs
#Scree plot ----
scree_plot = fviz_eig(data.pca,
addlabels = TRUE,
ylim = c(0, 70)) +
geom_col(color = "#00AFBB", fill = "#00AFBB")
scree_plot
scree_plot %>%
ggsave(file = here("Figuras", paste0("PCA_", nivel_selec ,"_", ano_selec, "_Screeplot.png")),
width = 5,
height = 3)
# Loadings plot ----
options(ggrepel.max.overlaps = Inf)
circle_contrib= fviz_pca_var(pca_res, col.var = "cos2",
gradient.cols = c("#65ADC2", "black"),
select.var= list(cos2 = 30),
repel = T,
labelsize = 4,
col.circle = NA)
circle_contrib
circle_contrib %>%
ggsave(file = here("Figuras", paste0("PCA_", nivel_selec ,"_", ano_selec, "_Loadings.png")),
width = 5,
height = 5)
# Cluster ------
#Determine the number of clusters
pca_scores <- data.frame(pca_res$x[, 1:2])
fviz_nbclust(pca_scores,
FUNcluster = kmeans,
method = "wss")
set.seed(666) # Set seed for randomization
cluster_model <- kmeans(pca_res$x[, 1:2], centers = 2) #Set the number of clusters
pca_dados$cluster <- as.factor(cluster_model$cluster)
pca_dados = pca_dados %>%
rownames_to_column("id")
# Plot ------
pca_plot_knn_cluster = autoplot(pca_res,
data = pca_dados,
colour = 'cluster') +
stat_ellipse(aes(color = cluster,
fill = cluster),
geom = "polygon",
alpha = 0.1,
linetype = 1,
size = 0.3,
type = "t") +
geom_point(aes(fill = cluster,
size = pop),
colour="black",
pch=21) +
labs(title = paste0(nivel_selec, "paulista, ", ano_selec)) +
theme(text = element_text(color = "black")) +
geom_label_repel(aes(label = id,
segment.colour= "black"),
box.padding = 0.3,
size = 3) +
scale_size_continuous(range = c(2,8))
pca_plot_knn_cluster_marginal = ggMarginal(
pca_plot_knn_cluster,
groupFill = T,
groupColour = T)
pca_plot_knn_cluster_marginal
pca_plot_knn_cluster_marginal %>% ggsave(file = here("Figuras", paste0("PCA_", nivel_selec ,"_", ano_selec, "_Clusters.png")), width = 10, height = 6)
ggthemr("fresh", spacing = 1)
swatch()
#Polio ----
pca_plot_knn_cluster_gradient = autoplot(pca_res,
data = pca_dados) +
geom_point(aes(fill = cob_vac_polio,
size = pop),
colour="black",
pch=21) +
labs(title = paste0(nivel_selec, "paulista, ", ano_selec)) +
theme(text = element_text(color = "black"),
legend.position = "right") +
scale_fill_gradient(low = "#E84646", high = "#65ADC2") +
scale_size_continuous(range = c(2,8))
pca_plot_knn_cluster_gradient
pca_plot_knn_cluster_gradient %>% ggsave(file = here("Figuras", paste0("PCA_", nivel_selec ,"_", ano_selec,"_Polio.png")), width = 10, height = 6)
#BCG -----
pca_plot_knn_cluster_gradient = autoplot(pca_res,
data = pca_dados) +
geom_point(aes(fill = cob_vac_bcg,
size = pop),
colour="black",
pch=21) +
labs(title = paste0(nivel_selec, "paulista, ", ano_selec)) +
theme(text = element_text(color = "black"),
legend.position = "right") +
scale_fill_gradient(low = "#E84646", high = "#65ADC2") +
scale_size_continuous(range = c(2,8))
pca_plot_knn_cluster_gradient
pca_plot_knn_cluster_gradient %>% ggsave(file = here("Figuras", paste0("PCA_", nivel_selec ,"_", ano_selec,"_BCG.png")), width = 10, height = 6)
"#111111" "#65ADC2" "#233B43" "#E84646" "#C29365" "#362C21" "#316675" "#168E7F" "#109B37"
res.km <- kmeans(var$coord, centers = 3, nstart = 25)
grp <- as.factor(res.km$cluster)
pca_plot_knn_cluster_biplot = fviz_pca_biplot(pca_res,
col.var = "black",
geom.var = c("point", "text"),
fill.ind = pca_dados$cluster,
col.ind = "black",
pointshape = 21,
palette = c("#65ADC2", "#233B43", "#E84646"),
label = "var",
select.var= list(cos2 = 20),
pointsize = 3,
addEllipses = T,
repel = TRUE,
legend.title = "Cluster")
pca_plot_knn_cluster_biplot
pca_plot_knn_cluster_biplot %>% ggsave(file = here("Figuras", paste0("PCA_", nivel_selec ,"_", ano_selec,"_Biplot.png")), width = 10, height = 6)
Microrregião: Dispersão
pop_regiao = IEPS_Completo_2010_2022_selecionados_SP %>%
filter(nivel == nivel_selec) %>%
mutate(porte_regiao = case_when(pop <= 20000 ~ "Pequeno Porte I",
pop <= 50000 ~ "Pequeno Porte II",
pop <= 100000 ~ "Médio Porte",
pop <= 900000 ~ "Grande Porte",
TRUE ~ "Metrópole")) %>%
select(row_names, porte_municipio)
dados_vacinas = IEPS_Completo_2010_2022_selecionados_SP %>%
filter(nivel == nivel_selec) %>%
select(row_names, ano, cob_ab:cob_vac_penta,
tx_mort_aj_cens:pct_desp_recp_saude_mun,
desp_tot_saude_pc_mun_def,
desp_recp_saude_pc_mun_def,
ideb_5ano:pop,
pct_pop_fem:pct_pop_masc) %>%
inner_join(pop_regiao, by = row_names) %>%
distinct()
Correlação ideb e vacina
# library(esquisse)
# library(ggpmisc)
cor_vac_ideb = dados_vacinas %>%
filter(!ano == ymd("2022-01-01")) %>%
select(c(row_names, "ideb_5ano", "ideb_9ano", "cob_vac_bcg", "ano", "porte_municipio", "pop")) %>%
ggplot(.) +
aes(x = ideb_5ano, y = cob_vac_bcg) +
# geom_point(color = "black",
# shape = "circle") +
geom_point(aes(fill = porte_municipio,
colour = porte_municipio,
size = pop),
shape = "circle") +
geom_smooth(method = "lm",
alpha = 0.1,
se = T) +
scale_y_continuous(expand = expansion(add = 20)) +
scale_size_continuous(range = c(2,8)) +
stat_correlation(method = "pearson",
size = 3.5,
label.x = 5,
label.y = 120,
mapping = use_label(c("R", "R2", "P", "n"))) +
theme(legend.position = "right",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
legend.text = element_text(size = 15),
strip.text.x = element_text(size = 15, face = "plain")) +
labs(title = "Cobertura vacinal da BCG e IDEB 5o ano, microrregiões do estado de São Paulo",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
color = "Microrregião",
y = "Cobertura vacinal (%)",
x = "IDEB") +
facet_wrap(~ano, scales = "free", nrow = 2)
cor_vac_ideb
cor_vac_ideb %>%
ggsave(file = here("Figuras", here("Figuras", paste0("PCA_", nivel_selec ,"_", ano_selec,"_2010_2020_BCG_vs_IDEB.png"))
width = 20,
height = 10)
IDHM e vacina
cor_vac_idhm = dados_vacinas %>%
filter(!ano == ymd("2022-01-01")) %>%
select(c("no_regiao", "idhm", "cob_vac_bcg", "ano", "porte_municipio", "pop")) %>%
ggplot(.) +
aes(x = idhm, y = cob_vac_bcg) +
# geom_point(color = "black",
# shape = "circle") +
geom_point(aes(fill = porte_municipio,
colour = porte_municipio,
size = pop),
shape = "circle") +
geom_smooth(method = "lm",
alpha = 0.1,
se = T) +
scale_y_continuous(expand = expansion(add = 20)) +
scale_size_continuous(range = c(2,8)) +
stat_correlation(method = "pearson",
size = 3.5,
label.x = 5,
label.y = 120,
mapping = use_label(c("R", "R2", "P", "n"))) +
theme(legend.position = "right",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
legend.text = element_text(size = 15),
strip.text.x = element_text(size = 15, face = "plain")) +
labs(title = "Cobertura vacinal da BCG e IDH municipal, microrregiões do estado de São Paulo",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
color = "Microrregião",
y = "Cobertura vacinal (%)",
x = "IDHM") +
facet_wrap(~ano, scales = "free", nrow = 2)
cor_vac_idhm
cor_vac_idhm %>%
ggsave(file = here("Figuras", "Microrregioes_2010_2020_BCG_vs_IDHM.png"),
width = 20, height = 10)
Taxa de mortes evitaveis e vacina
variavel_interesse = "tx_mort_evit_aj_cens"
cor_vac_txmortes = dados_vacinas %>%
filter(!ano == ymd("2022-01-01")) %>%
select(c("no_regiao", variavel_interesse, "cob_vac_bcg", "ano", "porte_municipio", "pop")) %>%
ggplot(.) +
aes(x = variavel_interesse, y = cob_vac_bcg) +
# geom_point(color = "black",
# shape = "circle") +
geom_point(aes(fill = porte_municipio,
colour = porte_municipio,
size = pop),
shape = "circle") +
geom_smooth(method = "lm",
alpha = 0.1,
se = T) +
scale_y_continuous(expand = expansion(add = 20)) +
scale_size_continuous(range = c(2,8)) +
stat_correlation(method = "pearson",
size = 3.5,
label.x = 5,
label.y = 120,
mapping = use_label(c("R", "R2", "P", "n"))) +
theme(legend.position = "right",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
legend.text = element_text(size = 15),
strip.text.x = element_text(size = 15, face = "plain")) +
labs(title = "Cobertura vacinal da BCG e Taxa de mortes evitaveis (CENSO), microrregiões do estado de São Paulo",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
color = "Microrregião",
y = "Taxa de mortes evitaveis (CENSO)",
x = "IDHM") +
facet_wrap(~ano, scales = "free", nrow = 2)
cor_vac_txmortes
cor_vac_txmortes %>%
ggsave(file = here("Figuras", "Microrregioes_2010_2020_BCG_vs_Taxa_Mortes_Evitaveis.png"),
width = 20, height = 10)
Município
library(tidyverse)
library(ggrepel) #load before factoextra
library(factoextra)
library(caret)
library(stats)
library(ggfortify)
library(ggplot2)
library(corrplot)
library(cowplot)
library(ggcorrplot)
library(ComplexHeatmap)
library(circlize)
library(ggExtra)
library(FactoMineR)
Muncípios: Selecionados
ano_selec = "2020-01-01"
nivel_selec = "Município"
row_names = "nomemun"
pca_municipio = IEPS_Completo_2010_2022_selecionados_SP %>%
filter(nivel == "Município",
ano == ymd(ano_selec)) %>%
column_to_rownames("nomemun") %>%
select(cob_ab:cob_vac_penta,
tx_mort_aj_cens:pct_desp_recp_saude_mun,
desp_tot_saude_pc_mun_def,
desp_recp_saude_pc_mun_def,
ideb_5ano:pop,
pct_pop_fem:pct_pop_masc)
pca_municipio_matrix = pca_municipio %>%
as.matrix()
dim(pca_municipio_matrix)
pca_municipio_ann = IEPS_Completo_2010_2022_selecionados_SP %>%
filter(nivel == "Município",
ano == ymd(ano_selec)) %>%
select(nomemun, pop) %>%
mutate(porte_municipio = case_when(pop <= 20000 ~ "Pequeno Porte I",
pop <= 50000 ~ "Pequeno Porte II",
pop <= 100000 ~ "Médio Porte",
pop <= 900000 ~ "Grande Porte",
TRUE ~ "Metrópole"),
ID = nomemun) %>%
select(-pop) %>%
column_to_rownames("nomemun")
pca_municipio %>%
ggplot()
# Delete columns with near 0 variance
nearZeroVarCols <- nearZeroVar(pca_municipio_matrix, saveMetrics = TRUE)
pca_municipio_matrix_pca <- pca_municipio_matrix[, !nearZeroVarCols$nzv]
pca_res <- prcomp(pca_municipio_matrix_pca, scale. = T)
# Correlation plot ----
corr_matrix = cor(pca_municipio_matrix_pca %>% scale())
var <- get_pca_var(pca_res)
corr_matrix_selec = corr_matrix %>%
as.data.frame() %>%
rownames_to_column("id") %>%
filter(str_detect(id, "cob_vac")) %>%
column_to_rownames("id") %>%
as.matrix()
p.mat = cor_pmat(pca_municipio_matrix_pca %>% scale())
p.mat_2 = cor_pmat(corr_matrix_selec %>% scale()) %>%
as.data.frame() %>%
rownames_to_column("id") %>%
inner_join(corr_matrix_selec %>% as.data.frame() %>% rownames_to_column("id") %>% select("id"), by = "id") %>%
column_to_rownames("id") %>%
as.matrix()
#Selecionados
png(file = here("Figuras", paste0("PCA_", nivel_selec ,"_", ano_selec, "_Selecionados_Corrplot.png")),
width = 15, height = 5,
units = "in",
res = 300)
corrplot(round(corr_matrix_selec, 2),
is.corr = TRUE,
tl.col = "black",
title = "Cobertura vacinal e indicadores sociais, economicos, demográficos e de saúde",
cex.main = 2,
method = "color",
p.mat = p.mat_2,
tl.srt = 45,
sig.level = c(0.05),
mar=c(1,0,4,0),
addCoef.col = 'black',
number.cex = 0.6,
insig = "blank",
col = colorRampPalette(c("#65ADC2", "white", "#E84646"))(11))
dev.off()
#Todos os indicadores
corrplot = ggcorrplot(corr_matrix, hc.order = TRUE,
method = "circle",
type = "full",
ggtheme = NULL,
outline.col = "white",
p.mat = p.mat,
sig.level = 0.05,
colors = c("#65ADC2", "white", "#E84646")) +
theme(axis.text.x = element_text(angle = 45, size = 10),
axis.text.y = element_text(size = 10)) +
labs(title = "Cobertura vacinal e indicadores sociais, economicos, demográficos e de saúde") +
theme(plot.title = element_text(size = 15, face = "bold"))
corrplot
corrplot %>%
ggsave(file = here("Figuras", "PCA_Municípios_2020_Corrplot.png"), width = 12, height = 10)
#PCA ----
data.pca = prcomp(corr_matrix) #PCA
summary(corr_matrix) #Retornar PCs
#Scree plot ----
scree_plot = fviz_eig(data.pca,
addlabels = TRUE,
ylim = c(0, 70)) +
geom_col(color = "#00AFBB", fill = "#00AFBB")
scree_plot
scree_plot %>%
ggsave(file = here("Figuras", "PCA_Municípios_2020_Selecionados_Screeplot.png"),
width = 5,
height = 3)
# Loadings plot ----
options(ggrepel.max.overlaps = Inf)
circle_contrib= fviz_pca_var(pca_res, col.var = "cos2",
gradient.cols = c("#65ADC2", "black"),
select.var= list(cos2 = 30),
repel = T,
labelsize = 4,
col.circle = NA)
circle_contrib
circle_contrib %>%
ggsave(file = here("Figuras", "PCA_Municípios_2020_Selecionados_Loadings.png"),
width = 5,
height = 5)
# Cluster ------
#Determine the number of clusters
pca_scores <- data.frame(pca_res$x[, 1:2])
fviz_nbclust(pca_scores,
FUNcluster = kmeans,
method = "wss")
set.seed(666) # Set seed for randomization
cluster_model <- kmeans(pca_res$x[, 1:2], centers = 3) #Set the number of clusters
pca_municipio$cluster <- as.factor(cluster_model$cluster)
pca_municipio = pca_municipio %>%
rownames_to_column("id")
# Plot ------
pca_plot_knn_cluster = autoplot(pca_res,
data = pca_municipio,
colour = 'cluster') +
stat_ellipse(aes(color = cluster,
fill = cluster),
geom = "polygon",
alpha = 0.1,
linetype = 1,
size = 0.3,
type = "t") +
geom_point(aes(fill = cluster,
size = pop),
colour="black",
pch=21) +
labs(title = "Municípios paulistas, 2020") +
theme(text = element_text(color = "black")) +
# geom_label_repel(aes(label = id,
# segment.colour= "black"),
# box.padding = 0.3,
# size = 3) +
scale_size_continuous(range = c(1,8))
pca_plot_knn_cluster_marginal = ggMarginal(
pca_plot_knn_cluster,
groupFill = T,
groupColour = T)
pca_plot_knn_cluster_marginal
pca_plot_knn_cluster_marginal %>% ggsave(file = here("Figuras", "PCA_Municípios_2020_Selecionados_Clusters.png"), width = 10, height = 6)
ggthemr("fresh", spacing = 1)
swatch()
pca_plot_knn_cluster_gradient = autoplot(pca_res,
data = pca_municipio) +
geom_point(aes(fill = cob_vac_polio,
size = pop),
colour="black",
pch=21) +
labs(title = "Microrregiões paulistas, 2020") +
theme(text = element_text(color = "black"),
legend.position = "right") +
scale_fill_gradient(low = "#E84646", high = "#65ADC2") +
scale_size_continuous(range = c(4,8))
pca_plot_knn_cluster_gradient
pca_plot_knn_cluster_gradient %>% ggsave(file = here("Figuras", "PCA_Municipios_2020_Selecionados_Polio.png"), width = 10, height = 6)
ggthemr("fresh", spacing = 1)
swatch()
pca_municipio_2 = pca_municipio %>%
bind_cols(pca_municipio_ann)
pca_plot_knn_cluster_gradient = autoplot(pca_res,
data = pca_municipio_2) +
geom_point(aes(fill = porte_municipio,
size = pop),
colour="black",
pch=21) +
labs(title = "Microrregiões paulistas, 2020") +
theme(text = element_text(color = "black"),
legend.position = "right") +
scale_size_continuous(range = c(4,8))
pca_plot_knn_cluster_gradient
pca_plot_knn_cluster_gradient %>% ggsave(file = here("Figuras", "PCA_Municipios_2020_Selecionados_PorteMunicpio.png"), width = 10, height = 6)
"#111111" "#65ADC2" "#233B43" "#E84646" "#C29365" "#362C21" "#316675" "#168E7F" "#109B37"
res.km <- kmeans(var$coord, centers = 3, nstart = 25)
grp <- as.factor(res.km$cluster)
pca_plot_knn_cluster_biplot = fviz_pca_biplot(pca_res,
col.var = "black",
geom.var = c("point", "text"),
fill.ind = pca_municipio$cluster,
col.ind = "black",
pointshape = 21,
palette = c("#65ADC2", "#233B43", "#E84646"),
label = "var",
select.var= list(cos2 = 20),
pointsize = 3,
addEllipses = T,
repel = TRUE,
legend.title = "Cluster")
pca_plot_knn_cluster_biplot
pca_plot_knn_cluster_biplot %>% ggsave(file = here("Figuras", "PCA_Municipios_2020_Selecionados_Biplot.png"), width = 10, height = 6)
Correlação: Dispersão
pop_municipio = IEPS_Completo_2010_2022_selecionados_SP %>%
filter(nivel == "Município") %>%
mutate(porte_municipio = case_when(pop <= 20000 ~ "Pequeno Porte I",
pop <= 50000 ~ "Pequeno Porte II",
pop <= 100000 ~ "Médio Porte",
pop <= 900000 ~ "Grande Porte",
TRUE ~ "Metrópole")) %>%
select(nomemun, porte_municipio)
dados_vacinas = IEPS_Completo_2010_2022_selecionados_SP %>%
filter(nivel == "Município") %>%
select(nomemun, ano, cob_ab:cob_vac_penta,
tx_mort_aj_cens:pct_desp_recp_saude_mun,
desp_tot_saude_pc_mun_def,
desp_recp_saude_pc_mun_def,
ideb_5ano:pop,
pct_pop_fem:pct_pop_masc) %>%
inner_join(pop_municipio, by = "nomemun") %>%
distinct()
Correlação ideb e vacina
# library(esquisse)
# library(ggpmisc)
cor_vac_ideb = dados_vacinas %>%
filter(!ano == ymd("2022-01-01")) %>%
select(c("nomemun", "ideb_5ano", "ideb_9ano", "cob_vac_bcg", "ano", "porte_municipio", "pop")) %>%
ggplot(.) +
aes(x = ideb_5ano, y = cob_vac_bcg) +
# geom_point(color = "black",
# shape = "circle") +
geom_point(aes(fill = porte_municipio,
colour = porte_municipio,
size = pop),
shape = "circle") +
geom_smooth(method = "lm",
alpha = 0.1,
se = T) +
scale_y_continuous(expand = expansion(add = 20)) +
scale_size_continuous(range = c(2,8)) +
stat_correlation(method = "pearson",
size = 3.5,
label.x = 5,
label.y = 120,
mapping = use_label(c("R", "R2", "P", "n"))) +
theme(legend.position = "right",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
legend.text = element_text(size = 15),
strip.text.x = element_text(size = 15, face = "plain")) +
labs(title = "Cobertura vacinal da BCG e IDEB 5o ano, municípios do estado de São Paulo",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
color = "Municipio",
y = "Cobertura vacinal (%)",
x = "IDEB") +
facet_wrap(~ano, scales = "free", nrow = 2)
cor_vac_ideb
cor_vac_ideb %>%
ggsave(file = here("Figuras", "Municipios_2010_2020_BCG_vs_IDEB.png"),
width = 20,
height = 10)
IDHM e vacina
cor_vac_idhm = dados_vacinas %>%
filter(!ano == ymd("2022-01-01")) %>%
select(c("nomemun", "idhm", "cob_vac_bcg", "ano", "porte_municipio", "pop")) %>%
ggplot(.) +
aes(x = idhm, y = cob_vac_bcg) +
# geom_point(color = "black",
# shape = "circle") +
geom_point(aes(fill = porte_municipio,
colour = porte_municipio,
size = pop),
shape = "circle") +
geom_smooth(method = "lm",
alpha = 0.1,
se = T) +
scale_y_continuous(expand = expansion(add = 20)) +
scale_size_continuous(range = c(2,8)) +
stat_correlation(method = "pearson",
size = 3.5,
label.x = 5,
label.y = 120,
mapping = use_label(c("R", "P"))) +
theme(legend.position = "right",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
legend.text = element_text(size = 15),
strip.text.x = element_text(size = 15, face = "plain")) +
labs(title = "Cobertura vacinal da BCG e IDH municipal, municípios do estado de São Paulo",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
color = "Porte do município",
y = "Cobertura vacinal (%)",
x = "IDHM") +
facet_wrap(~ano, scales = "free", nrow = 2)
cor_vac_idhm
cor_vac_idhm %>%
ggsave(file = here("Figuras", "Municípios_2010_2020_BCG_vs_IDHM.png"),
width = 20, height = 10)
Taxa de medicos e vacina
variavel_interesse = "tx_med"
cor_vac_txmed = dados_vacinas %>%
filter(!ano == ymd("2022-01-01")) %>%
select(c("nomemun", variavel_interesse, "cob_vac_bcg", "ano", "porte_municipio", "pop")) %>%
ggplot(.) +
aes(x = tx_med, y = cob_vac_bcg) +
geom_point(aes(fill = porte_municipio,
colour = porte_municipio,
size = pop),
shape = "circle") +
geom_smooth(method = "lm",
alpha = 0.1,
se = T) +
#scale_y_continuous(expand = expansion(add = 10)) +
scale_size_continuous(range = c(2,8)) +
stat_correlation(method = "pearson",
size = 3.5,
label.x = 5,
label.y = 50,
mapping = use_label(c("R", "P"))) +
theme(legend.position = "right",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
legend.text = element_text(size = 15),
strip.text.x = element_text(size = 15, face = "plain")) +
labs(title = "Cobertura vacinal da BCG e Taxa de medicos (CENSO), municípios do estado de São Paulo",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
color = "Porte municipal",
y = "Cobertura vainal",
x = "Taxa de medicos (1.000 hab)") +
facet_wrap(~ano, scales = "free", nrow = 2)
cor_vac_txmed
cor_vac_txmed %>%
ggsave(file = here("Figuras", "Municípios_2010_2020_BCG_vs_Taxa_Medicos.png"),
width = 20, height = 10)
variavel_interesse = "tx_med"
cor_vac_txmed = dados_vacinas %>%
filter(!ano == ymd("2022-01-01")) %>%
select(c("nomemun", variavel_interesse, "cob_vac_bcg", "ano", "porte_municipio", "pop")) %>%
mutate(tx_med = scale(tx_med)) %>%
ggplot(.) +
aes(x = tx_med, y = cob_vac_bcg) +
geom_point(aes(fill = porte_municipio,
colour = porte_municipio,
size = pop),
shape = "circle") +
geom_smooth(method = "lm",
alpha = 0.1,
se = T) +
#scale_y_continuous(expand = expansion(add = 10)) +
scale_size_continuous(range = c(2,8)) +
stat_correlation(method = "spearman",
size = 3.5,
label.x = 5,
label.y = 50,
mapping = use_label(c("R", "P"))) +
theme(legend.position = "right",
text = element_text(size = 15, color = "black"),
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 20),
plot.caption = element_text(size = 15),
plot.margin = unit(c(1,1,1,1), "cm"),
legend.text = element_text(size = 15),
strip.text.x = element_text(size = 15, face = "plain")) +
labs(title = "Cobertura vacinal da BCG e Taxa normalizada de medicos (CENSO), municípios do estado de São Paulo",
subtitle = "Período de 2010 a 2022",
caption = "Fonte: IEPS, PNI, TabNet/DATASUS",
color = "Porte municipal",
y = "Cobertura vacinal",
x = "Taxa de medicos (1.000 hab, normalizado)") +
facet_wrap(~ano, scales = "free", nrow = 2)
cor_vac_txmed
cor_vac_txmed %>%
ggsave(file = here("Figuras", "Municípios_2010_2020_BCG_vs_Taxa_Medicos_normalizada.png"),
width = 20, height = 10)
distributions_selec = IEPS_Completo_Regiao_SP %>%
filter(ano == ymd("2020-01-01")) %>%
drop_na(valor) %>%
group_by(variavel) %>%
mutate(valor = if_else(str_detect(variavel, "pop"), log10(valor), valor),
valor = if_else(!str_detect(variavel, "pop"), scale(valor), valor)) %>%
ggplot() +
aes(x = valor) +
geom_density(fill = "#65ADC2",
color = "#65ADC2") +
facet_wrap(~variavel, scales = "free")
distributions_selec %>%
ggsave(file = here("Figuras", "Região_2020_distribuicao_var_selecionadas.png"), width = 20, height = 15)
QQPLOT
IEPS_Completo_Regiao_SP %>%
filter(ano == ymd("2020-01-01")) %>%
drop_na(valor) %>%
group_by(variavel) %>%
mutate(valor = if_else(str_detect(variavel, "pop"), log10(valor), valor),
valor = if_else(!str_detect(variavel, "pop"), scale(valor), valor)) %>%
filter(variavel == "cob_vac_bcg") %>%
ggplot(mapping = aes(sample = valor)) +
stat_qq_band() +
stat_qq_line() +
stat_qq_point(fill = "black",
color = "black") +
labs(x = "Theoretical Quantiles", y = "Sample Quantiles")
LS0tDQp0aXRsZTogIlVQVmFjaW5hIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQplZGl0b3Jfb3B0aW9uczogDQogIG1hcmtkb3duOiANCiAgICB3cmFwOiA3Mg0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGRwaT02MDAsZmlnLndpZHRoPTUpDQpgYGANCg0KIyBCaWJsaW90ZWNhcw0KDQpgYGB7cn0NCiMgaW5zdGFsbC5wYWNrYWdlcygicXFwbG90ciIpDQojIGluc3RhbGwucGFja2FnZXMoIndyaXRleGwiKQ0KIyBkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoJ01pa2F0YS1Qcm9qZWN0L2dndGhlbXInKQ0KDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoaGVyZSkNCmxpYnJhcnkod3JpdGV4bCkNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShqYW5pdG9yKQ0KbGlicmFyeShzdHJpbmdpKQ0KbGlicmFyeShnZ3RoZW1lcykNCmxpYnJhcnkoZXNxdWlzc2UpDQpsaWJyYXJ5KGdndGhlbXIpDQpsaWJyYXJ5KGdncmlkZ2VzKQ0KbGlicmFyeShnckRldmljZXMpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkoZ2doaWdobGlnaHQpDQpsaWJyYXJ5KGdnc2NpKQ0KbGlicmFyeShwYXRjaHdvcmspDQpsaWJyYXJ5KHFxcGxvdHIpDQoNCmBgYA0KDQojIFVuaW5kbyB0YWJlbGFzDQoNCkRhZG9zIGRlIGVzdGFkb3MNCg0KYGBge3J9DQpsaXN0YV9VRl9jb2JlcnR1cmEgPSBsaXN0LmZpbGVzKCkgDQoNCiMgTGlzdGEgdG9kb3Mgb3MgYXJxdWl2b3MgQ1NWIG5vIGRpcmV0w7NyaW8NCmFycXVpdm9zX3hsc3ggPC0gbGlzdC5maWxlcyhoZXJlKCksIHBhdHRlcm4gPSAiXFwueGxzeCQiLCBmdWxsLm5hbWVzID0gRikNCg0KI0NyaWFyIGZ1bmNhbw0KcmVhZF94bF9zaXBuaSA8LSBmdW5jdGlvbihhcnF1aXZvKSB7DQogIGRhZG9zIDwtIHJlYWRfZXhjZWwoYXJxdWl2bywgc2tpcCA9IDQsIGNvbF9uYW1lcyA9IEZBTFNFKSAlPiUNCiAgICBzZXROYW1lcyguWzEsIF0pICU+JQ0KICAgIHNsaWNlKC0xOi00KSAlPiUNCiAgICBtdXRhdGUoYWNyb3NzKC0xLCBhcy5udW1lcmljKSkgJT4lICANCiAgICBwaXZvdF9sb25nZXIoY29scyA9IC1jKDEpLCANCiAgICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiaW11bm8iLCANCiAgICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gImNvYmVydHVyYSIpICU+JSANCiAgICBtdXRhdGUoYXJxdWl2byA9IGJhc2VuYW1lKGFycXVpdm8pKSAlPiUgDQogICAgamFuaXRvcjo6Y2xlYW5fbmFtZXMoKSAlPiUgDQogICAgbXV0YXRlKGNvYmVydHVyYSA9IHJvdW5kKGNvYmVydHVyYSwgMiksDQogICAgICAgICAgIGFubyA9IGFzLm51bWVyaWMoZ3N1YigiLipfKFxcZHs0fSlcXC54bHN4IiwgIlxcMSIsIGFycXVpdm8pKSwNCiAgICAgICAgICAgdWYgPSBnc3ViKCJcXGQiLCAiIiwgLltbMV1dKSkgICU+JSANCiAgICBzZWxlY3QoLXVuaWRhZGVfZGFfZmVkZXJhY2FvKSAlPiUgDQogICAgZmlsdGVyKCFpcy5uYSh1ZiksDQogICAgICAgICAgICFncmVwbCgiR2VyYWRvIiwgdWYpKSAlPiUgDQogICAgc2VsZWN0KHVmLCBhbm8sIGltdW5vLCBjb2JlcnR1cmEpICU+JSANCiAgICBncm91cF9ieSh1ZiwgYW5vLCBpbXVubykNCiAgDQogIHJldHVybihkYWRvcykNCn0NCg0KDQojIExlaWEsIGNvbnZlcnRhIGVtIHRhYmVsYSBsb25nYSBlIGNvbWJpbmUgb3MgYXJxdWl2b3MgQ1NWIGVtIHVtIMO6bmljbyBEYXRhRnJhbWUNCnNpcG5pX2NvYmVydHVyYV91Zl8xOTk0XzIwMjMgPC0gbGFwcGx5KGFycXVpdm9zX3hsc3gsIHJlYWRfeGxfc2lwbmkpICU+JQ0KICBiaW5kX3Jvd3MoKQ0KDQpzYXZlUkRTKHNpcG5pX2NvYmVydHVyYV91Zl8xOTk0XzIwMjMsIGZpbGUgPSAic2lwbmlfY29iZXJ0dXJhX3VmXzE5OTRfMjAyMy5yZHMiKQ0KYGBgDQoNCkRhZG9zIGRlIG11bmljw61waW9zDQoNCmBgYHtyfQ0KI0xpc3RhciB0YWJlbGFzDQpsaXN0YV9NVV9jb2JlcnR1cmEgPSBsaXN0LmZpbGVzKCkgDQphcnF1aXZvc194bHN4IDwtIGxpc3QuZmlsZXMoaGVyZSgpLCBwYXR0ZXJuID0gIlxcLnhsc3gkIiwgZnVsbC5uYW1lcyA9IEYpDQoNCiNDcmlhciBmdW7Dp8Ojbw0KcmVhZF94bF9zaXBuaV9tdW5pY2lwaW8gPC0gZnVuY3Rpb24oYXJxdWl2bykgew0KICBkYWRvcyA8LSByZWFkX2V4Y2VsKGFycXVpdm8sIHNraXAgPSA0LCBjb2xfbmFtZXMgPSBGQUxTRSkgJT4lDQogICAgc2V0TmFtZXMoLlsxLCBdKSAlPiUNCiAgICBzbGljZSgtMTotNCkgJT4lDQogICAgbXV0YXRlKGFjcm9zcygtMSwgYXMubnVtZXJpYykpICU+JSAgDQogICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSAtYygxKSwgDQogICAgICAgICAgICAgICAgIG5hbWVzX3RvID0gImltdW5vIiwgDQogICAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJjb2JlcnR1cmEiKSAlPiUgDQogICAgbXV0YXRlKGFycXVpdm8gPSBiYXNlbmFtZShhcnF1aXZvKSkgJT4lIA0KICAgIGphbml0b3I6OmNsZWFuX25hbWVzKCkgJT4lIA0KICAgIG11dGF0ZShjb2JlcnR1cmEgPSByb3VuZChjb2JlcnR1cmEsIDIpLA0KICAgICAgICAgICBhbm8gPSBhcy5udW1lcmljKGdzdWIoIi4qXyhcXGR7NH0pXFwueGxzeCIsICJcXDEiLCBhcnF1aXZvKSkpICU+JSANCiAgICBmaWx0ZXIoIWlzLm5hKG11bmljaXBpbyksDQogICAgICAgICAgICFncmVwbCgiR2VyYWRvIiwgbXVuaWNpcGlvKSkgJT4lIA0KICAgIHNlbGVjdChtdW5pY2lwaW8sIGFubywgaW11bm8sIGNvYmVydHVyYSkgJT4lIA0KICAgIGdyb3VwX2J5KG11bmljaXBpbywgYW5vLCBpbXVubykNCiAgDQogIHJldHVybihkYWRvcykNCn0NCg0KI1VuaXIgZGFkb3MNCnNpcG5pX2NvYmVydHVyYV9tdW5pY2lwaW9zXzE5OTRfMjAyMyA8LSBsYXBwbHkoYXJxdWl2b3NfeGxzeCwgcmVhZF94bF9zaXBuaV9tdW5pY2lwaW8pICU+JQ0KICBiaW5kX3Jvd3MoKQ0KDQojU2FsdmFyDQpzYXZlUkRTKHNpcG5pX2NvYmVydHVyYV9tdW5pY2lwaW9zXzE5OTRfMjAyMywgDQogICAgICAgICAgZmlsZSA9ICJzaXBuaV9jb2JlcnR1cmFfbXVuaWNpcGlvc18xOTk0XzIwMjMucmRzIikNCmBgYA0KDQojIFByb2Nlc3NhbWVudG8gZGUgZGFkb3MNCg0KYGBge3J9DQojRXN0YWRvcw0Kc2lwbmlfY29iZXJ0dXJhX3VmXzE5OTRfMjAyM18yID0gc2lwbmlfY29iZXJ0dXJhX3VmXzE5OTRfMjAyMyAlPiUgDQogIG11dGF0ZShtdW5fdWYgPSAiVUYiLCANCiAgICAgICAgIG5vbWUgPSB1ZiwNCiAgICAgICAgIG5vbWUgPSAgdG91cHBlcihub21lKSwNCiAgICAgICAgIG5vbWUgPSBzdHJpX3RyYW5zX2dlbmVyYWwobm9tZSwgIkxhdGluLUFTQ0lJIikpICU+JSANCiAgc2VsZWN0KG5vbWUsIHVmLCBhbm8sIGltdW5vLCBjb2JlcnR1cmEsIG11bl91ZikNCg0Kc2F2ZVJEUyhzaXBuaV9jb2JlcnR1cmFfdWZfMTk5NF8yMDIzXzIsIGZpbGUgPSAic2lwbmlfY29iZXJ0dXJhX3VmXzE5OTRfMjAyM18yLnJkcyIpDQoNCiNNdW5pY8OtcGlvcw0Kc2lwbmlfY29iZXJ0dXJhX211bmljaXBpb3NfMTk5NF8yMDIzXzIgPSBzaXBuaV9jb2JlcnR1cmFfbXVuaWNpcGlvc18xOTk0XzIwMjMgJT4lIA0KIG11dGF0ZShjb2RpZ28gPSBhcy5jaGFyYWN0ZXIoc3RyX2V4dHJhY3QobXVuaWNpcGlvLCAiXFxkKyIpKSwjIEV4dHJhaXIgbsO6bWVyb3MNCiAgICAgICAgbm9tZSA9IHN0cl9yZW1vdmUobXVuaWNpcGlvLCAiXFxkKyAiKSwjIEV4dHJhaXIgdGV4dG8NCiAgICAgICAgbXVuX3VmID0gIk11bmljw61waW8iICkgJT4lIA0KICBzZWxlY3QoISIuLi4xIjptdW5pY2lwaW8pDQoNCmdsaW1wc2Uoc2lwbmlfY29iZXJ0dXJhX211bmljaXBpb3NfMTk5NF8yMDIzXzIpDQoNCiMgI1VuaXINCiMgc2lwbmlfYWxsID0gYmluZF9yb3dzKHNpcG5pX2NvYmVydHVyYV91Zl8xOTk0XzIwMjNfMiwgc2lwbmlfY29iZXJ0dXJhX211bmljaXBpb3NfMTk5NF8yMDIzXzIpDQojIHdyaXRlLmNzdihzaXBuaV9hbGwsIGZpbGUgPSAic2lwbmlfdWZfbXVuXzE5OTRfMjAyMy5jc3YiKQ0KDQpgYGANCg0KI0Fub3RhciBtdW5pY2lwaW9zIGUgZXN0YWRvcw0KDQpgYGB7cn0NCiNBbm90YcOnw7VlcyBkZSBjaWRhZGVzLiBGb250ZTogSUJHRS4gaHR0cHM6Ly93d3cuaWJnZS5nb3YuYnIvZXhwbGljYS9jb2RpZ29zLWRvcy1tdW5pY2lwaW9zLnBocA0KZHRiX211bmljaXBpb3NfY29kID0gUkVMQVRPUklPX0RUQl9CUkFTSUxfTVVOSUNJUElPICU+JSANCiAgY2xlYW5fbmFtZXMoKSAlPiUgDQogIHNlbGVjdChjb2RpZ29fdWYgPSB1ZiwgdWYgPSBub21lX3VmLCBjb2RpZ28gPSBjb2RpZ29fbXVuaWNpcGlvX2NvbXBsZXRvLCBub21lX211bmljaXBpbykgJT4lIA0KICBtdXRhdGUobm9tZV9tdW5pY2lwaW9fb3JpZ2luYWwgPSBub21lX211bmljaXBpbywNCiAgICAgICAgIG5vbWUgPSAgdG91cHBlcihub21lX211bmljaXBpb19vcmlnaW5hbCksDQogICAgICAgICBub21lID0gc3RyaV90cmFuc19nZW5lcmFsKG5vbWUsICJMYXRpbi1BU0NJSSIpKSAlPiUgDQogIHNlbGVjdCgtbm9tZV9tdW5pY2lwaW8pDQoNCm11bmljaXBpb3MgPSBzaXBuaV9jb2JlcnR1cmFfbXVuaWNpcGlvc18xOTk0XzIwMjNfMiAlPiUgDQogIG11dGF0ZShub21lID0gZ3N1YigiXFxcXCIsICIiLCBub21lKSkgJT4lIA0KICBsZWZ0X2pvaW4oZHRiX211bmljaXBpb3NfY29kLCBieSA9ICJub21lIikgJT4lIA0KICBzZWxlY3Qobm9tZSwgbm9tZV9tdW5pY2lwaW9fb3JpZ2luYWwsIHVmLCBjb2RpZ29fbXVuaWNpcGlvID0gY29kaWdvLnksIGFubywgaW11bm8sIGNvYmVydHVyYSwgY29kaWdvX3VmLCBtdW5fdWYpDQoNCiNTYWx2YXINCnNhdmVSRFMobXVuaWNpcGlvcywgZmlsZSA9ICJzaXBuaV9jb2JlcnR1cmFfbXVuaWNpcGlvc18xOTk0XzIwMjNfMi5yZHMiKQ0KICANCmBgYA0KDQojQW7DoWxpc2UgZGUgZGFkb3MgT3MgZGFkb3MgZGFzIHBvcHVsYcOnw7VlcyBmb3JhbSBvYnRpZG9zIGRvcyBhbm9zIDIwMDAgYQ0KMjAyMiwgcG9pcyBvcyBhbm9zIDIwMDcgZSAyMDIzIG7Do28gZXN0YXZhbSBkaXNwb27DrXZlaXMuIERlZmluaXINCnZhcmnDoXZlaXMgLQ0KPGh0dHBzOi8vd3d3LmliZ2UuZ292LmJyL2VzdGF0aXN0aWNhcy9kb3dubG9hZHMtZXN0YXRpc3RpY2FzLmh0bWw+IC0NCkNlbnNvcyAtIFBlcmZpbCBFc3RhZG9zIC0gUGVyZmlsIE11bmljaXBpb3MgLSBFY29ub21pY29zIC0gSW5kaWNhZG9yZXMNCnNvY2lhaXMgLSBFZHVjYWNhw6fDo28gZSBxdWFsaWZpY2HDp8OjbyBwcm9maXNzaW9uYWwgLSBFY29ub21pYSBkZSBzYcO6ZGUgLQ0KQWNlc3NvIMOgIGludGVybmV0IC0gRWR1Y2HDp8OjbyAtIFNhw7pkZQ0KDQpgYGB7cn0NCmluc3RhbGwucGFja2FnZXMoImJhc2Vkb3NkYWRvcyIpDQpsaWJyYXJ5KCJiYXNlZG9zZGFkb3MiKQ0KDQojIFBhcmEgY2FycmVnYXIgbyBkYWRvIGRpcmV0byBubyBSDQpxdWVyeSA8LSBiZHBseXIoImJyX2liZ2VfY2Vuc29fZGVtb2dyYWZpY28ubWljcm9kYWRvc19kb21pY2lsaW9fMTk3MCIpDQpkZiA8LSBiZF9jb2xsZWN0KHF1ZXJ5KQ0KDQoNCmluc3RhbGwucGFja2FnZXMoImJkcGx5ciIpDQpxdWVyeSA8LSBiZHBseXIoImJyX21zX2F0ZW5jYW9fYmFzaWNhLm11bmljaXBpbyIpDQpkZiA8LSBiZF9jb2xsZWN0KHF1ZXJ5KQ0KDQpgYGANCg0KYGBge3J9DQojIFBvcHVsYcOnw6NvIC0tLS0gDQoNCiMgT2J0ZXIgcG9wdWxhw6fDo28gZGUgbXVuaWNpcGlvcy4NCmFub3MgPSAyMDAwOjIwMjMNCnJlc3VsdGFkb3MgPSBsaXN0KCkNCmZvciAoYW5vIGluIGFub3MpIHsNCiAgdHJ5Q2F0Y2goew0KICAgICMgQ2hhbWFyIGEgZnVuw6fDo28gcG9wdWxhY2FvX211bmljaXBpb3MgcGFyYSBvIGFubyBhdHVhbCBlIGFybWF6ZW5hciBvIHJlc3VsdGFkbyBuYSBsaXN0YQ0KICAgIGRmX2FubyA8LSBwb3B1bGFjYW9fbXVuaWNpcGlvcyhhbm8pDQogICAgZGZfYW5vIDwtIGRmX2FubyAlPiUNCiAgICAgIG11dGF0ZV9hbGwoYXMuY2hhcmFjdGVyKSAgIyBDb252ZXJ0ZW5kbyB0b2RhcyBhcyBjb2x1bmFzIHBhcmEgY2hhcmFjdGVyDQogICAgcmVzdWx0YWRvc1tbYXMuY2hhcmFjdGVyKGFubyldXSA8LSBkZl9hbm8NCiAgfSwgZXJyb3IgPSBmdW5jdGlvbihlKSB7DQogICAgIyBUcmF0YXIgbyBlcnJvIChwb3IgZXhlbXBsbywgaW1wcmltaXIgdW1hIG1lbnNhZ2VtKQ0KICAgIHByaW50KHBhc3RlKCJFcnJvIHBhcmEgbyBhbm8iLCBhbm8sICI6IiwgY29uZGl0aW9uTWVzc2FnZShlKSkpDQogIH0pDQp9DQoNCiMgQ29tYmluYXIgdG9kb3Mgb3MgZGF0YWZyYW1lcyBlbSB1bSDDum5pY28gZGF0YWZyYW1lDQpwb3B1bGFjYW9fbXVuaWNpcGlvc18yMDAwXzIwMjIgPC0gYmluZF9yb3dzKHJlc3VsdGFkb3MsIC5pZCA9ICJhbm8iKSAlPiUgDQogIHNlbGVjdCh1Zl9hYnJldiA9IHVmLCANCiAgICAgICAgIG5vbWVfbXVuaWNpcGlvX29yaWdpbmFsID0gbm9tZV9tdW5pYywNCiAgICAgICAgIGFubywgY29kaWdvX3VmLCANCiAgICAgICAgIHBvcHVsYWNhbywgDQogICAgICAgICBjb2RpZ29fbXVuaWNpcGlvID0gY29kX211bmljaXBpbykgJT4lIA0KICBtdXRhdGUoYW5vID0gYXMubnVtZXJpYyhhbm8pLA0KICAgICAgICAgcG9wdWxhY2FvID0gYXMubnVtZXJpYyhwb3B1bGFjYW8pKQ0KICANCnByaW50KHBvcHVsYWNhb19tdW5pY2lwaW9zXzIwMDBfMjAyMikNCg0KDQojIEdEUCAtLS0tDQoNCmFub3MgPSAxOTk5OjIwMjANCnBpYl9tdW5pY2lwaW9zKGFubyA9IDIwMDMpDQoNCnJlc3VsdGFkb3MgPSBsaXN0KCkNCmZvciAoYW5vIGluIGFub3MpIHsNCiAgdHJ5Q2F0Y2goew0KICAgIGRmX2FubyA8LSBwaWJfbXVuaWNpcGlvcyhhbm8gPSBhbm8sIGRpcj0iLiIpDQogICAgcmVzdWx0YWRvc1tbYW5vXV0gPC0gZGZfYW5vDQogIH0sIGVycm9yID0gZnVuY3Rpb24oZSkgew0KICAgIHByaW50KHBhc3RlKCJFcnJvIHBhcmEgbyBhbm8iLCBhbm8sICI6IiwgY29uZGl0aW9uTWVzc2FnZShlKSkpDQogIH0pDQp9DQoNCiMgQ29tYmluYXIgdG9kb3Mgb3MgZGF0YWZyYW1lcyBlbSB1bSDDum5pY28gZGF0YWZyYW1lDQpwb3B1bGFjYW9fbXVuaWNpcGlvc18yMDAwXzIwMjIgPC0gYmluZF9yb3dzKHJlc3VsdGFkb3MsIC5pZCA9ICJhbm8iKSAlPiUgDQogIHNlbGVjdCh1Zl9hYnJldiA9IHVmLCANCiAgICAgICAgIG5vbWVfbXVuaWNpcGlvX29yaWdpbmFsID0gbm9tZV9tdW5pYywNCiAgICAgICAgIGFubywgY29kaWdvX3VmLCANCiAgICAgICAgIHBvcHVsYWNhbywgDQogICAgICAgICBjb2RpZ29fbXVuaWNpcGlvID0gY29kX211bmljaXBpbykgJT4lIA0KICBtdXRhdGUoYW5vID0gYXMubnVtZXJpYyhhbm8pLA0KICAgICAgICAgcG9wdWxhY2FvID0gYXMubnVtZXJpYyhwb3B1bGFjYW8pKQ0KICANCnByaW50KHBvcHVsYWNhb19tdW5pY2lwaW9zXzIwMDBfMjAyMikNCmBgYA0KDQpgYGB7cn0NCiNVbmlyIGRhZG9zDQoNCm11bmljaXBpb3NfMiA9IG11bmljaXBpb3MgJT4lIA0KIGxlZnRfam9pbihwb3B1bGFjYW9fbXVuaWNpcGlvc18yMDAwXzIwMjIgJT4lIA0KICAgICAgICAgICAgIHNlbGVjdChjb2RpZ29fbXVuaWNpcGlvLCBhbm8sIHBvcHVsYWNhbyksDQogICAgICAgICAgICBieSA9IGMoImNvZGlnb19tdW5pY2lwaW8iLCAiYW5vIikpDQpgYGANCg0KI0lFUFMgZGFkb3MNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiNVbmlyIGRhZG9zDQpJRVBTX0JyYXNpbF8yMDEwXzIwMjJfVG9kb3MgPC0gcmVhZF9leGNlbCgiZGFkb3NfYnJ1dG9zL0lFUFMvSUVQU19CcmFzaWxfMjAxMF8yMDIyX1RvZG9zLnhsc3giKSAlPiUgDQogIG11dGF0ZShuaXZlbCA9ICJCcmFzaWwiKQ0KSUVQU19Fc3RhZG9zXzIwMTBfMjAyMl9Ub2RvcyA8LSByZWFkX2V4Y2VsKCJkYWRvc19icnV0b3MvSUVQUy9JRVBTX0VzdGFkb3NfMjAxMF8yMDIyX1RvZG9zLnhsc3giKSAlPiUgDQogIG11dGF0ZShuaXZlbCA9ICJFc3RhZG8iKQ0KSUVQU19NYWNyb1JlZ2lhb18yMDEwXzIwMjJfVG9kb3MgPC0gcmVhZF9leGNlbCgiZGFkb3NfYnJ1dG9zL0lFUFMvSUVQU19NYWNyb1JlZ2lhb18yMDEwXzIwMjJfVG9kb3MueGxzeCIpICU+JSANCiAgbXV0YXRlKG5pdmVsID0gIk1hY3JvIFJlZ2nDo28iKQ0KSUVQU19NdW5pY2lwaW9zXzIwMTBfMjAyMl9Ub2RvcyA8LSByZWFkX2V4Y2VsKCJkYWRvc19icnV0b3MvSUVQUy9JRVBTX011bmljaXBpb3NfMjAxMF8yMDIyX1RvZG9zLnhsc3giKSAlPiUgDQogIG11dGF0ZShuaXZlbCA9ICJNdW5pY8OtcGlvIikNCklFUFNfUmVnaWFvXzIwMTBfMjAyMl9Ub2RvcyA8LSByZWFkX2V4Y2VsKCJkYWRvc19icnV0b3MvSUVQUy9JRVBTX1JlZ2lhb18yMDEwXzIwMjJfVG9kb3MueGxzeCIpICU+JSANCiAgbXV0YXRlKG5pdmVsID0gIlJlZ2nDo28iKQ0KDQpJRVBTX0NvbXBsZXRvXzIwMTBfMjAyMl9Ub2RvcyA9IGJpbmRfcm93cyhJRVBTX0JyYXNpbF8yMDEwXzIwMjJfVG9kb3MsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRVBTX0VzdGFkb3NfMjAxMF8yMDIyX1RvZG9zLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSUVQU19NYWNyb1JlZ2lhb18yMDEwXzIwMjJfVG9kb3MsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRVBTX1JlZ2lhb18yMDEwXzIwMjJfVG9kb3MsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRVBTX011bmljaXBpb3NfMjAxMF8yMDIyX1RvZG9zKSANCg0KI1BhZHJvbml6YXIgdGFiZWxhcw0KDQpJRVBTX0JyYXNpbF8yMDEwXzIwMjJfVG9kb3MgPC0gSUVQU19CcmFzaWxfMjAxMF8yMDIyX1RvZG9zICU+JSANCiAgbXV0YXRlKG5pdmVsID0gIkJyYXNpbCIpICU+JSANCiAgbXV0YXRlKGFjcm9zcyhjKGNvYl9hYjpwY3RfcG9wX21hc2MpLCB+IHN0cl9yZXBsYWNlKC4sICIsIiwgIi4iKSkpICU+JSANCiAgbXV0YXRlKGFjcm9zcyhjKGNvYl9hYjpwY3RfcG9wX21hc2MpLCB+IGFzLm51bWVyaWMoLikpKSAlPiUgDQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnltZChhbm8sIHRydW5jYXRlZCA9IDJMKSkNCg0KSUVQU19Fc3RhZG9zXzIwMTBfMjAyMl9Ub2RvcyA8LSBJRVBTX0VzdGFkb3NfMjAxMF8yMDIyX1RvZG9zICU+JSANCiAgbXV0YXRlKG5pdmVsID0gIkVzdGFkbyIpICU+JSANCiAgbXV0YXRlKGFjcm9zcyhjKGNvYl9hYjpwY3RfcG9wX21hc2MpLCB+IHN0cl9yZXBsYWNlKC4sICIsIiwgIi4iKSkpICU+JSANCiAgbXV0YXRlKGFjcm9zcyhjKGNvYl9hYjpwY3RfcG9wX21hc2MpLCB+IGFzLm51bWVyaWMoLikpKSAlPiUgDQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnltZChhbm8sIHRydW5jYXRlZCA9IDJMKSkNCg0KSUVQU19NYWNyb1JlZ2lhb18yMDEwXzIwMjJfVG9kb3MgPC0gSUVQU19NYWNyb1JlZ2lhb18yMDEwXzIwMjJfVG9kb3MgJT4lIA0KICBtdXRhdGUobml2ZWwgPSAiTWFjcm8gUmVnacOjbyIpICU+JSANCiAgbXV0YXRlKGFjcm9zcyhjKGNvYl9hYjpwY3RfcG9wX21hc2MpLCB+IHN0cl9yZXBsYWNlKC4sICIsIiwgIi4iKSkpICU+JSANCiAgbXV0YXRlKGFjcm9zcyhjKGNvYl9hYjpwY3RfcG9wX21hc2MpLCB+IGFzLm51bWVyaWMoLikpKSAlPiUgDQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnltZChhbm8sIHRydW5jYXRlZCA9IDJMKSkNCg0KSUVQU19SZWdpYW9fMjAxMF8yMDIyX1RvZG9zIDwtIElFUFNfUmVnaWFvXzIwMTBfMjAyMl9Ub2RvcyAlPiUgDQogIG11dGF0ZShuaXZlbCA9ICJSZWdpw6NvIikgJT4lIA0KICBtdXRhdGUoYWNyb3NzKGMoY29iX2FiOnBjdF9wb3BfbWFzYyksIH4gc3RyX3JlcGxhY2UoLiwgIiwiLCAiLiIpKSkgJT4lIA0KICBtdXRhdGUoYWNyb3NzKGMoY29iX2FiOnBjdF9wb3BfbWFzYyksIH4gYXMubnVtZXJpYyguKSkpICU+JSANCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eW1kKGFubywgdHJ1bmNhdGVkID0gMkwpKQ0KDQpJRVBTX011bmljaXBpb3NfMjAxMF8yMDIyX1RvZG9zIDwtIElFUFNfTXVuaWNpcGlvc18yMDEwXzIwMjJfVG9kb3MgJT4lIA0KICBtdXRhdGUobml2ZWwgPSAiTXVuaWPDrXBpbyIsDQogICAgICAgICBwb3J0ZV9tdW5pY2lwaW8gPSBjYXNlX3doZW4ocG9wIDw9IDIwMDAwIH4gIk11bmljw61waW8gZGUgUGVxdWVubyBQb3J0ZSBJIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3AgPD0gNTAwMDAgfiAiTXVuaWPDrXBpbyBkZSBQZXF1ZW5vIFBvcnRlIElJIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3AgPD0gMTAwMDAwIH4gIk11bmljw61waW8gZGUgTcOpZGlvIFBvcnRlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3AgPD0gOTAwMDAwIH4gIk11bmljw61waW8gZGUgR3JhbmRlIFBvcnRlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gIk1ldHLDs3BvbGUiKSkgJT4lIA0KICBtdXRhdGUoYWNyb3NzKGMoY29iX2FiOnBjdF9wb3BfbWFzYyksIH4gc3RyX3JlcGxhY2UoLiwgIiwiLCAiLiIpKSkgJT4lIA0KICBtdXRhdGUoYWNyb3NzKGMoY29iX2FiOnBjdF9wb3BfbWFzYyksIH4gYXMubnVtZXJpYyguKSkpICU+JSANCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eW1kKGFubywgdHJ1bmNhdGVkID0gMkwpKQ0KDQpJRVBTX0NvbXBsZXRvXzIwMTBfMjAyMl9Ub2RvcyA9IElFUFNfQ29tcGxldG9fMjAxMF8yMDIyX1RvZG9zICU+JSANCiAgbXV0YXRlKGFjcm9zcyhjKGNvYl9hYjpwY3RfcG9wX21hc2MpLCB+IHN0cl9yZXBsYWNlKC4sICIsIiwgIi4iKSkpICU+JSANCiAgbXV0YXRlKGFjcm9zcyhjKGNvYl9hYjpwY3RfcG9wX21hc2MpLCB+IGFzLm51bWVyaWMoLikpKSAlPiUgDQogIG11dGF0ZShhbm8gPSBsdWJyaWRhdGU6OnltZChhbm8sIHRydW5jYXRlZCA9IDJMKSkNCg0KSUVQU19Db21wbGV0b18yMDEwXzIwMjJfVG9kb3MgJT4lIA0KICBzYXZlUkRTKGZpbGUgPSBoZXJlKCJkYWRvc19wcm9jZXNzYWRvcyIsICJJRVBTX0NvbXBsZXRvXzIwMTBfMjAyMl9Ub2Rvcy5yZHMiKSkNCg0KDQpgYGANCg0KU2VsZcOnw6NvIGRlIHZhcmnDoXZlaXMNCg0KYGBge3J9DQojQ29udmVydGVyIC5jc3YgcGFyYSAueGxzeA0KSUVQU19jb2RlYm9vayA8LSByZWFkX2RlbGltKCJkYWRvc19icnV0b3MvSUVQUy9JRVBTX2NvZGVib29rLmNzdiIsIGRlbGltID0gIjsiLCBlc2NhcGVfZG91YmxlID0gRkFMU0UsIHRyaW1fd3MgPSBUUlVFKQ0KDQpJRVBTX2NvZGVib29rICU+JSANCiAgd3JpdGVfeGxzeChoZXJlKCJkYWRvc19icnV0b3MiLCAiSUVQUyIsJ0lFUFNfY29kZWJvb2sueGxzeCcpKQ0KDQojTGltcGFyIHRhYmVsYQ0KSUVQU192YXJfc2VsZWNpb25hZGFzID0gcmVhZF9leGNlbCgiZGFkb3NfcHJvY2Vzc2Fkb3MvSUVQU19jb2RlYm9va19zZWxlY2lvbmFkb3MueGxzeCIpICU+JSANCiAgY2xlYW5fbmFtZXMoKSAlPiUgDQogIGZpbHRlcihzZWxlY2FvID09ICJTaW0iKSAlPiUgDQogIG11dGF0ZShibG9jbyA9IGlmX2Vsc2Uoc3RyX2RldGVjdCh2YXJpYXZlbCwgImNvYl92YWMiKSwgIkNvYmVydHVyYSB2YWNpbmFsIiwgYmxvY28pKQ0KDQojRmlsdHJhciB0YWJlbGEgZSBjb252ZXJ0ZXIgdGV4dG8gcGFyYSBudW3DqXJpY28NCklFUFNfQ29tcGxldG9fMjAxMF8yMDIyX1RvZG9zIDwtIHJlYWRSRFMoaGVyZSgiZGFkb3NfcHJvY2Vzc2Fkb3MiLCAiSUVQU19Db21wbGV0b18yMDEwXzIwMjJfVG9kb3MucmRzIikpDQoNCklFUFNfQ29tcGxldG9fMjAxMF8yMDIyX3NlbGVjaW9uYWRvcyA9IElFUFNfQ29tcGxldG9fMjAxMF8yMDIyX1RvZG9zICU+JSANCiAgc2VsZWN0KG5pdmVsLCBhbm8sIGlkX2VzdGFkbzpub21lbXVuLCBJRVBTX3Zhcl9zZWxlY2lvbmFkYXMkdmFyaWF2ZWwpDQoNCklFUFNfQ29tcGxldG9fMjAxMF8yMDIyX3NlbGVjaW9uYWRvcyAlPiUgDQogIHNhdmVSRFMoZmlsZSA9IGhlcmUoImRhZG9zX3Byb2Nlc3NhZG9zIiwgIklFUFNfQ29tcGxldG9fMjAxMF8yMDIyX3NlbGVjaW9uYWRvcy5yZHMiKSkNCg0KI0RhZG9zIGRlIFPDo28gUGF1bG8NCklFUFNfQ29tcGxldG9fMjAxMF8yMDIyX3NlbGVjaW9uYWRvc19TUCA9IElFUFNfQ29tcGxldG9fMjAxMF8yMDIyX3NlbGVjaW9uYWRvcyAlPiUgDQogIGZpbHRlcihlc3RhZG9fYWJyZXYgPT0gIlNQIikNCg0KSUVQU19Db21wbGV0b18yMDEwXzIwMjJfc2VsZWNpb25hZG9zX1NQICU+JSANCiAgc2F2ZVJEUyhmaWxlID0gaGVyZSgiZGFkb3NfcHJvY2Vzc2Fkb3MiLCAiSUVQU19Db21wbGV0b18yMDEwXzIwMjJfc2VsZWNpb25hZG9zX1NQLnJkcyIpKQ0KDQoNCmBgYA0KDQojQW7DoWxpc2UgZXhwbG9yYXTDs3JpYQ0KYGBge3IgZmlnLmhlaWdodD03LCBmaWcud2lkdGg9MTJ9DQojRGVmaW5pciB0ZW1hDQpnZ3RoZW1yKCJmcmVzaCIsIHNwYWNpbmcgPSAxKQ0KYGBgDQoNCiMjIEJyYXNpbA0KDQpgYGB7ciBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD0xMn0NCmJyYXNpbF92YWNpbmFzID0gSUVQU19Db21wbGV0b18yMDEwXzIwMjJfc2VsZWNpb25hZG9zICU+JSANCiAgZmlsdGVyKG5pdmVsICVpbiUgYygiQnJhc2lsIikpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjb2JfdmFjX2JjZzpjb2JfdmFjX2hlcGEsDQogICAgICAgICAgICAgICBuYW1lc190byA9ICJ2YXJpYXZlbCIsDQogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidmFsb3IiKSAlPiUgDQogIGlubmVyX2pvaW4oSUVQU192YXJfc2VsZWNpb25hZGFzLCBieSA9ICJ2YXJpYXZlbCIpICU+JSANCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eW1kKGFubywgdHJ1bmNhdGVkID0gMkwpKQ0KDQoNCg0KYnJhc2lsX3ZhY2luYXNfcGxvdCA9IGJyYXNpbF92YWNpbmFzICU+JSANCm11dGF0ZShub21lX2Rvc19pbmRpY2Fkb3JlcyA9IHN0cl9yZXBsYWNlKG5vbWVfZG9zX2luZGljYWRvcmVzLCAiQ29iZXJ0dXJhIFZhY2luYWwgZGUgIiwgIiIpLA0KICAgICAgIG5vbWVfZG9zX2luZGljYWRvcmVzID0gc3RyX3JlcGxhY2Uobm9tZV9kb3NfaW5kaWNhZG9yZXMsICJcXChcXCVcXCkiLCAiIikpICU+JSANCiAgZ2dwbG90KCkgKw0KICBhZXMoeCA9IGFubywgeSA9IHZhbG9yKSArDQogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICIxIHllYXIiLCBkYXRlX2xhYmVscyA9ICIleSIpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGV4cGFuc2lvbihhZGQgPSAxMCkpICsNCiAgZ2VvbV9yZWN0KHhtaW4gPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMTYtMDEtMDEiKSksDQogICAgICAgICAgIHhtYXggPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMjAtMDEtMDEiKSksDQogICAgICAgICAgICB5bWluID0gMCwNCiAgICAgICAgICAgIHltYXggPSAxMTAsDQogICAgICAgICAgICBmaWxsID0gImdyYXkiLA0KICAgICAgICAgICAgYWxwaGEgPSAwLjAzKSArDQogIGdlb21fcmVjdCh4bWluID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIwLTAxLTAxIikpLA0KICAgICAgICAgICAgICAgeG1heCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAyMi0wMS0wMSIpKSwNCiAgICAgICAgICAgICAgICB5bWluID0gMCwNCiAgICAgICAgICAgICAgICB5bWF4ID0gMTEwLA0KICAgICAgICAgICAgICAgIGZpbGwgPSAiZ3JheTQwIiwNCiAgICAgICAgICAgICAgICBhbHBoYSA9IDAuMDMpICsNCiAgZ2VvbV9saW5lKHNpemUgPSAyLCBjb2xvciA9ICIjNjVBREMyIikgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIpLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksDQogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSBtYXJnaW4oNSwgNSwgMTUsIDUsICJwdCIpKSkgKw0KICBsYWJzKHRpdGxlID0gIkNvYmVydHVyYSB2YWNpbmFsIG5vIEJyYXNpbCIsDQogICAgICAgc3VidGl0bGUgPSAiUGVyw61vZG8gZGUgMjAxMCBhIDIwMjIiLA0KICAgICAgIGNhcHRpb24gPSAiRm9udGU6IElFUFMsIFBOSSwgVGFiTmV0L0RBVEFTVVMiLA0KICAgICAgIHkgPSAiQ29iZXJ0dXJhIHZhY2luYWwgKCUpIiwNCiAgICAgICB4ID0gIiIpICsNCiAgZmFjZXRfd3JhcCh+bm9tZV9kb3NfaW5kaWNhZG9yZXMsIHNjYWxlcyA9ICJmcmVlIikNCg0KDQpnZ3NhdmUoYnJhc2lsX3ZhY2luYXNfcGxvdCwgZmlsZSA9IGhlcmUoIkZpZ3VyYXMiLCAiVmFjaW5hc19CcmFzaWxfMjAxMF8yMDIyLnBuZyIpLCB3aWR0aCA9IDE1LCBoZWlnaHQgPSA4KQ0KDQpgYGANCg0KIyMgRXN0YWRvcw0KYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE1fQ0KZXN0YWRvc19iY2cgPSBJRVBTX0NvbXBsZXRvXzIwMTBfMjAyMl9zZWxlY2lvbmFkb3MgJT4lIA0KICBmaWx0ZXIobml2ZWwgPT0gIkVzdGFkbyIpICU+JSANCiAgZ2dwbG90KC4pICsNCiAgYWVzKHggPSBhbm8sIHkgPSBjb2JfdmFjX2JjZykgKw0KICBmYWNldF93cmFwKHZhcnMoZXN0YWRvKSwgbnJvdyA9IDQpICsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjEgeWVhciIsIGRhdGVfbGFiZWxzID0gIiV5IikgKw0KICBnZW9tX3JlY3QoeG1pbiA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAxNi0wMS0wMSIpKSwNCiAgICAgICAgICAgeG1heCA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAyMC0wMS0wMSIpKSwNCiAgICAgICAgICAgIHltaW4gPSAwLA0KICAgICAgICAgICAgeW1heCA9IDExMCwNCiAgICAgICAgICAgIGZpbGwgPSAiZ3JheSIsDQogICAgICAgICAgICBhbHBoYSA9IDAuMDMpICsNCiAgZ2VvbV9yZWN0KHhtaW4gPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMjAtMDEtMDEiKSksDQogICAgICAgICAgICAgICB4bWF4ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIyLTAxLTAxIikpLA0KICAgICAgICAgICAgICAgIHltaW4gPSAwLA0KICAgICAgICAgICAgICAgIHltYXggPSAxMTAsDQogICAgICAgICAgICAgICAgZmlsbCA9ICJncmF5NDAiLA0KICAgICAgICAgICAgICAgIGFscGhhID0gMC4wMykgKw0KICBnZW9tX2xpbmUoc2l6ZSA9IDIsIGNvbG9yID0gIiM2NUFEQzIiKSArDQogIHRoZW1lKHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLCBjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMSwwLDAsMCksICJjbSIpLA0KICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBmYWNlID0gImJvbGQiKSkgKw0KICBsYWJzKHRpdGxlID0gIkNvYmVydHVyYSB2YWNpbmFsIGRhIEJDRyBub3MgZXN0YWRvcyIsDQogICAgICAgc3VidGl0bGUgPSAiUGVyw61vZG8gZGUgMjAxMCBhIDIwMjIiLA0KICAgICAgIGNhcHRpb24gPSAiRm9udGU6IElFUFMsIFBOSSwgVGFiTmV0L0RBVEFTVVMiLA0KICAgICAgIHkgPSAiQ29iZXJ0dXJhIHZhY2luYWwgKCUpIiwNCiAgICAgICB4ID0gIiIpDQogIA0KICBlc3RhZG9zX2JjZyAlPiUgZ2dzYXZlKGZpbGUgPSBoZXJlKCJGaWd1cmFzIiwgIlZhY2luYXNfRXN0YWRvc18yMDEwXzIwMjJfQkNHLnBuZyIpLCB3aWR0aCA9IDIwLCBoZWlnaHQgPSAxMCkNCiAgDQpgYGANCg0KDQoNCg0KIyMgU8OjbyBQYXVsbw0KDQoNCmBgYHtyIGZpZy5oZWlnaHQ9NywgZmlnLndpZHRoPTEyfQ0KI0ltcG9ydGFyIGRhZG9zDQpJRVBTX0NvbXBsZXRvXzIwMTBfMjAyMl9zZWxlY2lvbmFkb3NfU1AgPC0gcmVhZFJEUyhoZXJlKCJkYWRvc19wcm9jZXNzYWRvcyIsICJJRVBTX0NvbXBsZXRvXzIwMTBfMjAyMl9zZWxlY2lvbmFkb3NfU1AucmRzIikpIA0KSUVQU192YXJfc2VsZWNpb25hZGFzID0gcmVhZF9leGNlbCgiZGFkb3NfcHJvY2Vzc2Fkb3MvSUVQU19jb2RlYm9va19zZWxlY2lvbmFkb3MueGxzeCIpICU+JSANCiAgY2xlYW5fbmFtZXMoKSAlPiUgDQogIGZpbHRlcihzZWxlY2FvID09ICJTaW0iKSAlPiUgDQogIG11dGF0ZShibG9jbyA9IGlmX2Vsc2Uoc3RyX2RldGVjdCh2YXJpYXZlbCwgImNvYl92YWMiKSwgIkNvYmVydHVyYSB2YWNpbmFsIiwgYmxvY28pKQ0KDQojTWFuaXB1bGHDp8Ojbw0KSUVQU19Db21wbGV0b19maWx0cmFkb19TUCA9IElFUFNfQ29tcGxldG9fMjAxMF8yMDIyX3NlbGVjaW9uYWRvc19TUCAlPiUgDQogIGZpbHRlcihuaXZlbCA9PSAiRXN0YWRvIikgJT4lIA0KICBwaXZvdF9sb25nZXIoY29scyA9IGNvYl9hYjpwY3RfcG9wX21hc2MsDQogICAgICAgICAgICAgICBuYW1lc190byA9ICJ2YXJpYXZlbCIsDQogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidmFsb3IiKSAlPiUgDQogIGlubmVyX2pvaW4oSUVQU192YXJfc2VsZWNpb25hZGFzLCBieSA9ICJ2YXJpYXZlbCIpICU+JSANCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eW1kKGFubywgdHJ1bmNhdGVkID0gMkwpKQ0KDQoNCklFUFNfQ29tcGxldG9fUmVnaWFvX1NQID0gSUVQU19Db21wbGV0b18yMDEwXzIwMjJfc2VsZWNpb25hZG9zX1NQICU+JSANCiAgZmlsdGVyKG5pdmVsID09ICJSZWdpw6NvIikgJT4lIA0KICBwaXZvdF9sb25nZXIoY29scyA9IGNvYl9hYjpwY3RfcG9wX21hc2MsDQogICAgICAgICAgICAgICBuYW1lc190byA9ICJ2YXJpYXZlbCIsDQogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidmFsb3IiKSAlPiUgDQogIGlubmVyX2pvaW4oSUVQU192YXJfc2VsZWNpb25hZGFzLCBieSA9ICJ2YXJpYXZlbCIpICU+JSANCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eW1kKGFubywgdHJ1bmNhdGVkID0gMkwpKQ0KDQoNCklFUFNfQ29tcGxldG9fTXVuaWNpcGlvX1NQID0gSUVQU19Db21wbGV0b18yMDEwXzIwMjJfc2VsZWNpb25hZG9zX1NQICU+JSANCiAgZmlsdGVyKG5pdmVsID09ICJNdW5pY8OtcGlvIikgJT4lIA0KICBwaXZvdF9sb25nZXIoY29scyA9IGNvYl9hYjpwY3RfcG9wX21hc2MsDQogICAgICAgICAgICAgICBuYW1lc190byA9ICJ2YXJpYXZlbCIsDQogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidmFsb3IiKSAlPiUgDQogIGlubmVyX2pvaW4oSUVQU192YXJfc2VsZWNpb25hZGFzLCBieSA9ICJ2YXJpYXZlbCIpICU+JSANCiAgbXV0YXRlKGFubyA9IGx1YnJpZGF0ZTo6eW1kKGFubywgdHJ1bmNhdGVkID0gMkwpKQ0KDQoNCklFUFNfQ29tcGxldG9fUmVnaWFvX1NQX3ZhY2luYXMgPSBJRVBTX0NvbXBsZXRvX1JlZ2lhb19TUCAlPiUgDQogIGZpbHRlcihzdHJfZGV0ZWN0KG5vbWVfZG9zX2luZGljYWRvcmVzLCAiQ29iZXJ0dXJhIFZhY2luYWwiKSkgJT4lIA0KICBzZWxlY3QoYW5vLCByZWdpYW8sIG5vX3JlZ2lhbywgbm9tZV9kb3NfaW5kaWNhZG9yZXMsIHZhbG9yKSAlPiUgDQogIG11dGF0ZSh2YWxvciA9IHJvdW5kKHZhbG9yLCAyKSwNCiAgICAgICAgIGFubyA9IGFzLmNoYXJhY3Rlcihhbm8pICU+JSBzdHJfcmVwbGFjZSguLCAiLTAxLTAxIiwgIiIpLA0KICAgICAgICAgbm9tZV9kb3NfaW5kaWNhZG9yZXMgPSBzdHJfcmVwbGFjZShub21lX2Rvc19pbmRpY2Fkb3JlcywgIkNvYmVydHVyYSBWYWNpbmFsIGRlICIsICIiKSwNCiAgICAgICAgIG5vbWVfZG9zX2luZGljYWRvcmVzID0gc3RyX3JlcGxhY2Uobm9tZV9kb3NfaW5kaWNhZG9yZXMsICIgXFwoXFwlXFwpIiwgIiIpKQ0KDQoNCklFUFNfQ29tcGxldG9fTXVuaWNpcGlvX1NQX3ZhY2luYXMgPSBJRVBTX0NvbXBsZXRvX011bmljaXBpb19TUCAlPiUgDQogIGZpbHRlcihzdHJfZGV0ZWN0KG5vbWVfZG9zX2luZGljYWRvcmVzLCAiQ29iZXJ0dXJhIFZhY2luYWwiKSkgJT4lIA0KICBzZWxlY3QoYW5vLCByZWdpYW8sIG5vbWVtdW4sIG5vbWVfZG9zX2luZGljYWRvcmVzLCB2YWxvcikgJT4lIA0KICBtdXRhdGUodmFsb3IgPSByb3VuZCh2YWxvciwgMiksDQogICAgICAgICBhbm8gPSBhcy5jaGFyYWN0ZXIoYW5vKSAlPiUgc3RyX3JlcGxhY2UoLiwgIi0wMS0wMSIsICIiKSwNCiAgICAgICAgIG5vbWVfZG9zX2luZGljYWRvcmVzID0gc3RyX3JlcGxhY2Uobm9tZV9kb3NfaW5kaWNhZG9yZXMsICJDb2JlcnR1cmEgVmFjaW5hbCBkZSAiLCAiIiksDQogICAgICAgICBub21lX2Rvc19pbmRpY2Fkb3JlcyA9IHN0cl9yZXBsYWNlKG5vbWVfZG9zX2luZGljYWRvcmVzLCAiIFxcKFxcJVxcKSIsICIiKSkNCg0KYGBgDQoNClF1YWlzIHJlZ2nDtWVzIHRpdmVyYW0gY29iZXJ0dXJhIHZhY2luYWwgbcOtbmltYSBkZSA5MCUgZW50cmUgMjAxNSBlIDIwMjI/DQpJc3RvIMOpLCBxdWFpcyByZWdpw7VlcyBmb3JhbSBtZW5vcyBhZmV0YWRhcyBwZWxvIGVmZWl0byAyMDE2IGUgcGVsYQ0KcGFuZGVtaWE/DQoNCmBgYHtyfQ0KDQojUmVnacO1ZXMgLS0tLS0NCmRhZG9zX3ZhY2luYXMgPSBJRVBTX0NvbXBsZXRvX1JlZ2lhb19TUCAlPiUgDQogIGZpbHRlcihzdHJfZGV0ZWN0KG5vbWVfZG9zX2luZGljYWRvcmVzLCAiQ29iZXJ0dXJhIFZhY2luYWwiKSkgJT4lIA0KICBzZWxlY3QoYW5vLCByZWdpYW8sIG5vX3JlZ2lhbywgbm9tZV9kb3NfaW5kaWNhZG9yZXMsIHZhbG9yKSAlPiUgDQogIG11dGF0ZSh2YWxvciA9IHJvdW5kKHZhbG9yLCAyKSwNCiAgICAgICAgIG5vbWVfZG9zX2luZGljYWRvcmVzID0gc3RyX3JlcGxhY2Uobm9tZV9kb3NfaW5kaWNhZG9yZXMsICJDb2JlcnR1cmEgVmFjaW5hbCBkZSAiLCAiIiksDQogICAgICAgICBub21lX2Rvc19pbmRpY2Fkb3JlcyA9IHN0cl9yZXBsYWNlKG5vbWVfZG9zX2luZGljYWRvcmVzLCAiIFxcKFxcJVxcKSIsICIiKSkgJT4lIA0KICBkcm9wX25hKCkNCg0KI1NlbGVjaW9uYXIgcmVnacO1ZXMgY29tIGNvYmVydHVyYSB2YWNpbmFsIG3DrW5pbWEgZGUgOTAlDQpyZWdpb2VzX2FjaW1hXzkwID0gZGFkb3NfdmFjaW5hcyAlPiUgDQogIGZpbHRlcihhbm8gPj0geW1kKCIyMDE1LTAxLTAxIikgJiBhbm8gPD0geW1kKCIyMDIyLTAxLTAxIikpICU+JSANCiAgZ3JvdXBfYnkobm9fcmVnaWFvLCBub21lX2Rvc19pbmRpY2Fkb3JlcykgJT4lIA0KICBzdW1tYXJpc2UobWluX2NvdmVyYWdlID0gbWluKHZhbG9yKSkgJT4lDQogIGZpbHRlcihtaW5fY292ZXJhZ2UgPiA5MCkNCg0KI011bmljw61waW9zIC0tLS0tLQ0KZGFkb3NfdmFjaW5hcyA9IElFUFNfQ29tcGxldG9fTXVuaWNpcGlvX1NQICU+JSANCiAgZmlsdGVyKHN0cl9kZXRlY3Qobm9tZV9kb3NfaW5kaWNhZG9yZXMsICJDb2JlcnR1cmEgVmFjaW5hbCIpKSAlPiUgDQogIHNlbGVjdChhbm8sIHJlZ2lhbywgbm9tZW11biwgbm9tZV9kb3NfaW5kaWNhZG9yZXMsIHZhbG9yKSAlPiUgDQogIG11dGF0ZSh2YWxvciA9IHJvdW5kKHZhbG9yLCAyKSwNCiAgICAgICAgIG5vbWVfZG9zX2luZGljYWRvcmVzID0gc3RyX3JlcGxhY2Uobm9tZV9kb3NfaW5kaWNhZG9yZXMsICJDb2JlcnR1cmEgVmFjaW5hbCBkZSAiLCAiIiksDQogICAgICAgICBub21lX2Rvc19pbmRpY2Fkb3JlcyA9IHN0cl9yZXBsYWNlKG5vbWVfZG9zX2luZGljYWRvcmVzLCAiIFxcKFxcJVxcKSIsICIiKSkgJT4lIA0KICBkcm9wX25hKCkNCg0KI1NlbGVjaW9uYXIgbXVuaWNpcGlvcyBjb20gY29iZXJ0dXJhIHZhY2luYWwgbcOtbmltYSBkZSA5MCUNCm11bmljaXBpb3NfYWNpbWFfOTAgPSBkYWRvc192YWNpbmFzICU+JSANCiAgZmlsdGVyKGFubyA+PSB5bWQoIjIwMTUtMDEtMDEiKSAmIGFubyA8PSB5bWQoIjIwMjItMDEtMDEiKSkgJT4lIA0KICBncm91cF9ieShub21lbXVuLCBub21lX2Rvc19pbmRpY2Fkb3JlcykgJT4lIA0KICBzdW1tYXJpc2UobWluX2NvdmVyYWdlID0gbWluKHZhbG9yKSkgJT4lDQogIGZpbHRlcihtaW5fY292ZXJhZ2UgPiA5MCkNCmBgYA0KDQpRdWFpcyBmb3JhbSBhcyByZWdpw7VlcyBxdWUgbWFpcyB0aXZlcmFtIHJlZHXDp8OjbyBkYSBjb2JlcnR1cmEgdmFjaW5hbCBwb3INCnZhY2luYT8NCg0KYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE1fQ0KIyBDYWxjdWxhciBhIHZhcmlhw6fDo28gYW51YWwgZSBmaWx0cmFyIHZhcmlhw6fDtWVzIG5lZ2F0aXZhcw0KdmFyaWFjb2VzX25lZ2F0aXZhcyA8LSBkYWRvc192YWNpbmFzICU+JQ0KICAgIGRyb3BfbmEoKSAlPiUgDQogIGFycmFuZ2Uobm9fcmVnaWFvLCBub21lX2Rvc19pbmRpY2Fkb3JlcywgYW5vKSAlPiUNCiAgZ3JvdXBfYnkobm9fcmVnaWFvLCBub21lX2Rvc19pbmRpY2Fkb3JlcykgJT4lDQogIG11dGF0ZSh2YXJpYWNhb19hbnVhbCA9IHZhbG9yIC0gbGFnKHZhbG9yKSkgJT4lDQogIGdyb3VwX2J5KG5vbWVfZG9zX2luZGljYWRvcmVzKSAlPiUgDQogIGFycmFuZ2Uobm9tZV9kb3NfaW5kaWNhZG9yZXMsIHZhcmlhY2FvX2FudWFsKSAgJT4lIA0KICBmaWx0ZXIodmFyaWFjYW9fYW51YWw8MCkNCg0KI1RvcCA1IHJlZ2nDtWVzIGNvbSBtYWlvciBxdWVkYSBkYSBjb2JlcnR1cmEgdmFjaW5hbA0KdmFyaWFjb2VzX25lZ2F0aXZhc190b3A1ID0gdmFyaWFjb2VzX25lZ2F0aXZhcyAlPiUgDQogIHNsaWNlX21pbihuID0gNSwgb3JkZXJfYnkgPSB2YXJpYWNhb19hbnVhbCkNCnRvcDVfcmVkdXpfMjAxNiA9IHZhcmlhY29lc19uZWdhdGl2YXMgJT4lIA0KICBmaWx0ZXIoYW5vID09ICIyMDE2LTAxLTAxIikgICU+JSANCiAgc2xpY2VfbWluKG4gPSA1LCBvcmRlcl9ieSA9IHZhcmlhY2FvX2FudWFsKQ0KdG9wNV9yZWR1el8yMDIwID0gdmFyaWFjb2VzX25lZ2F0aXZhcyAlPiUgDQogIGZpbHRlcihhbm8gPT0gIjIwMjAtMDEtMDEiKSAgJT4lIA0KICBzbGljZV9taW4obiA9IDUsIG9yZGVyX2J5ID0gdmFyaWFjYW9fYW51YWwpDQoNCiNUb3AgNSByZWdpw7VlcyBjb20gbWFpb3IgcXVlZGEgZGEgY29iZXJ0dXJhIGRlIEJDRw0KYmNnX3RvcDVfcmVkdXpfMjAxNiA9IHZhcmlhY29lc19uZWdhdGl2YXMgJT4lIA0KICBmaWx0ZXIoYW5vID09ICIyMDE2LTAxLTAxIiwgDQogICAgICAgICBub21lX2Rvc19pbmRpY2Fkb3JlcyA9PSAiQkNHIikgICU+JSANCiAgc2xpY2VfbWluKG4gPSA1LCBvcmRlcl9ieSA9IHZhcmlhY2FvX2FudWFsKQ0KYmNnX3RvcDVfcmVkdXpfMjAyMCA9IHZhcmlhY29lc19uZWdhdGl2YXMgJT4lIA0KICBmaWx0ZXIoYW5vID09ICIyMDIwLTAxLTAxIiwgDQogICAgICAgICBub21lX2Rvc19pbmRpY2Fkb3JlcyA9PSAiQkNHIikgICU+JSANCiAgc2xpY2VfbWluKG4gPSA1LCBvcmRlcl9ieSA9IHZhcmlhY2FvX2FudWFsKQ0KDQpiY2dfdG9wNV9yZWR1el8yMDE2DQpiY2dfdG9wNV9yZWR1el8yMDIwDQpgYGANCg0KRSBvcyBtdW5pY8OtcGlvcz8NCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xNX0NCiMgQ2FsY3VsYXIgYSB2YXJpYcOnw6NvIGFudWFsIGUgZmlsdHJhciB2YXJpYcOnw7VlcyBuZWdhdGl2YXMNCnZhcmlhY29lc19uZWdhdGl2YXMgPC0gZGFkb3NfdmFjaW5hcyAlPiUNCiAgICBkcm9wX25hKCkgJT4lIA0KICBhcnJhbmdlKG5vbWVtdW4sIG5vbWVfZG9zX2luZGljYWRvcmVzLCBhbm8pICU+JQ0KICBncm91cF9ieShub21lbXVuLCBub21lX2Rvc19pbmRpY2Fkb3JlcykgJT4lDQogIG11dGF0ZSh2YXJpYWNhb19hbnVhbCA9IHZhbG9yIC0gbGFnKHZhbG9yKSkgJT4lDQogIGdyb3VwX2J5KG5vbWVfZG9zX2luZGljYWRvcmVzKSAlPiUgDQogIGFycmFuZ2Uobm9tZV9kb3NfaW5kaWNhZG9yZXMsIHZhcmlhY2FvX2FudWFsKSAgJT4lIA0KICBmaWx0ZXIodmFyaWFjYW9fYW51YWw8MCkNCg0KI1RvcCA1IHJlZ2nDtWVzIGNvbSBtYWlvciBxdWVkYSBkYSBjb2JlcnR1cmEgdmFjaW5hbA0KdmFyaWFjb2VzX25lZ2F0aXZhc190b3A1X211biA9IHZhcmlhY29lc19uZWdhdGl2YXMgJT4lIA0KICBzbGljZV9taW4obiA9IDUsIG9yZGVyX2J5ID0gdmFyaWFjYW9fYW51YWwpDQp0b3A1X3JlZHV6XzIwMTZfbXVuID0gdmFyaWFjb2VzX25lZ2F0aXZhcyAlPiUgDQogIGZpbHRlcihhbm8gPT0gIjIwMTYtMDEtMDEiKSAgJT4lIA0KICBzbGljZV9taW4obiA9IDUsIG9yZGVyX2J5ID0gdmFyaWFjYW9fYW51YWwpDQp0b3A1X3JlZHV6XzIwMjBfbXVuID0gdmFyaWFjb2VzX25lZ2F0aXZhcyAlPiUgDQogIGZpbHRlcihhbm8gPT0gIjIwMjAtMDEtMDEiKSAgJT4lIA0KICBzbGljZV9taW4obiA9IDUsIG9yZGVyX2J5ID0gdmFyaWFjYW9fYW51YWwpDQoNCiNUb3AgNSByZWdpw7VlcyBjb20gbWFpb3IgcXVlZGEgZGEgY29iZXJ0dXJhIGRlIEJDRw0KYmNnX3RvcDVfcmVkdXpfMjAxNl9tdW4gPSB2YXJpYWNvZXNfbmVnYXRpdmFzICU+JSANCiAgZmlsdGVyKGFubyA9PSAiMjAxNi0wMS0wMSIsIA0KICAgICAgICAgbm9tZV9kb3NfaW5kaWNhZG9yZXMgPT0gIkJDRyIpICAlPiUgDQogIHNsaWNlX21pbihuID0gNSwgb3JkZXJfYnkgPSB2YXJpYWNhb19hbnVhbCkNCmJjZ190b3A1X3JlZHV6XzIwMjBfbXVuID0gdmFyaWFjb2VzX25lZ2F0aXZhcyAlPiUgDQogIGZpbHRlcihhbm8gPT0gIjIwMjAtMDEtMDEiLCANCiAgICAgICAgIG5vbWVfZG9zX2luZGljYWRvcmVzID09ICJCQ0ciKSAgJT4lIA0KICBzbGljZV9taW4obiA9IDUsIG9yZGVyX2J5ID0gdmFyaWFjYW9fYW51YWwpDQoNCmJjZ190b3A1X3JlZHV6XzIwMTZfbXVuDQpiY2dfdG9wNV9yZWR1el8yMDIwX211bg0KYGBgDQoNCg0KYGBge3IgZmlnLmhlaWdodD03LCBmaWcud2lkdGg9MTJ9DQp2YWNpbmFzX2VzdGFkb19zcCA9IElFUFNfQ29tcGxldG9fZmlsdHJhZG9fU1AgJT4lIA0KICBmaWx0ZXIoYmxvY28gPT0gIkNvYmVydHVyYSB2YWNpbmFsIikgJT4lIA0KICBiaW5kX3Jvd3MoYnJhc2lsX3ZhY2luYXMpICU+JSANCiAgbXV0YXRlKG5pdmVsID0gaWZfZWxzZShuaXZlbCA9PSAiRXN0YWRvIiwgIlPDo28gUGF1bG8iLCBuaXZlbCksDQogICAgICAgICBub21lX2Rvc19pbmRpY2Fkb3JlcyA9IHN0cl9yZXBsYWNlKG5vbWVfZG9zX2luZGljYWRvcmVzLCAiQ29iZXJ0dXJhIFZhY2luYWwgZGUgIiwgIiIpLA0KICAgICAgICAgbm9tZV9kb3NfaW5kaWNhZG9yZXMgPSBzdHJfcmVwbGFjZShub21lX2Rvc19pbmRpY2Fkb3JlcywgIiBcXChcXCVcXCkiLCAiIiksDQogICAgICAgICBuaXZlbCA9IGZjdF9yZXYobml2ZWwpKSAlPiUgDQogIGdncGxvdCgpICsNCiAgYWVzKHggPSBhbm8sIHkgPSB2YWxvciwgZ3JvdXAgPSBuaXZlbCkgKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiMSB5ZWFyIiwgZGF0ZV9sYWJlbHMgPSAiJXkiKSArDQogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBleHBhbnNpb24oYWRkID0gMTApKSArDQogIGdlb21fcmVjdCh4bWluID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDE2LTAxLTAxIikpLA0KICAgICAgICAgICB4bWF4ID0gYXMubnVtZXJpYyhhcy5EYXRlKCIyMDIwLTAxLTAxIikpLA0KICAgICAgICAgICAgeW1pbiA9IDAsDQogICAgICAgICAgICB5bWF4ID0gMTEwLA0KICAgICAgICAgICAgZmlsbCA9ICJncmF5IiwNCiAgICAgICAgICAgIGFscGhhID0gMC4wMykgKw0KICBnZW9tX3JlY3QoeG1pbiA9IGFzLm51bWVyaWMoYXMuRGF0ZSgiMjAyMC0wMS0wMSIpKSwNCiAgICAgICAgICAgICAgIHhtYXggPSBhcy5udW1lcmljKGFzLkRhdGUoIjIwMjItMDEtMDEiKSksDQogICAgICAgICAgICAgICAgeW1pbiA9IDAsDQogICAgICAgICAgICAgICAgeW1heCA9IDExMCwNCiAgICAgICAgICAgICAgICBmaWxsID0gImdyYXk0MCIsDQogICAgICAgICAgICAgICAgYWxwaGEgPSAwLjAzKSArDQogIGdlb21fbGluZShzaXplID0gMiwgbWFwcGluZyA9IGFlcyhjb2xvciA9IG5pdmVsLCBsaW5ldHlwZSA9IG5pdmVsKSkgKw0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLA0KICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luID0gbWFyZ2luKDUsIDUsIDE1LCA1LCAicHQiKSkpICsNCiAgbGFicyh0aXRsZSA9ICJDb2JlcnR1cmEgdmFjaW5hbCBubyBlc3RhZG8gZGUgU8OjbyBQYXVsbyIsDQogICAgICAgc3VidGl0bGUgPSAiUGVyw61vZG8gZGUgMjAxMCBhIDIwMjIiLA0KICAgICAgIGNhcHRpb24gPSAiRm9udGU6IElFUFMsIFBOSSwgVGFiTmV0L0RBVEFTVVMiLA0KICAgICAgIGNvbG9yID0gIiIsDQogICAgICAgeSA9ICJDb2JlcnR1cmEgdmFjaW5hbCAoJSkiLA0KICAgICAgIHggPSAiIikgKw0KICBmYWNldF93cmFwKH5ub21lX2Rvc19pbmRpY2Fkb3Jlcywgc2NhbGVzID0gImZyZWUiKQ0KDQp2YWNpbmFzX2VzdGFkb19zcCAlPiUgDQogIGdnc2F2ZShmaWxlID0gaGVyZSgiRmlndXJhcyIsICJWYWNpbmFzX0JyYXNpbF9TUF8yMDEwXzIwMjJfbGluaGFzLnBuZyIpLCB3aWR0aCA9IDEyLCBoZWlnaHQgPSA3KQ0KDQp2YWNpbmFzX2VzdGFkb19zcA0KYGBgDQoNCiNBbsOhbGlzZSBwb3IgbWljcm9ycmVnacOjbw0KDQojIyBEZW5zaWRhZGUNCg0KYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE1fQ0KSUVQU19Db21wbGV0b19SZWdpYW9fU1BfdmFjaW5hc19yaWRnZSA9IElFUFNfQ29tcGxldG9fUmVnaWFvX1NQX3ZhY2luYXMgJT4lIA0KICBkcm9wX25hKCkgJT4lIA0KICBnZ3Bsb3QoKSArDQogIGFlcyh4ID0gdmFsb3IsIHkgPSBmY3RfcmV2KGFubyksIGZpbGwgPSBhbm8pICsNCiAgZ2VvbV9kZW5zaXR5X3JpZGdlcygpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3JSYW1wUGFsZXR0ZShjKCIjNjVBREMyIiwgInB1cnBsZSIpKSgxNSkpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjUpLA0KICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksDQogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBwYW5lbC5zcGFjaW5nPXVuaXQoMiwgImxpbmVzIikpICsNCiAgbGFicyh0aXRsZSA9ICJDb2JlcnR1cmEgdmFjaW5hbCIsDQogICAgICAgc3VidGl0bGUgPSAiUGVyw61vZG8gZGUgMjAxMCBhIDIwMjIiLA0KICAgICAgIGNhcHRpb24gPSAiRm9udGU6IElFUFMsIFBOSSwgVGFiTmV0L0RBVEFTVVMiLA0KICAgICAgIHkgPSAiIiwNCiAgICAgICB4ID0gIkNvYmVydHVyYSB2YWNpbmFsICglKSIpICsNCiAgICBmYWNldF93cmFwKH5ub21lX2Rvc19pbmRpY2Fkb3Jlcywgc2NhbGVzID0gImZyZWVfeCIsIG5yb3cgPSAyKQ0KICANCklFUFNfQ29tcGxldG9fUmVnaWFvX1NQX3ZhY2luYXNfcmlkZ2UgJT4lIA0KICAgIGdnc2F2ZShmaWxlID0gaGVyZSgiRmlndXJhcyIsICJ2YWNpbmFzX3JlZ2lvZXNfZXN0YWRvX3NwXzIwMTBfMjAyMl9kZW5zaWRhZGUucG5nIiksIHdpZHRoID0gMTUsIGhlaWdodCA9IDEwKQ0KDQpJRVBTX0NvbXBsZXRvX1JlZ2lhb19TUF92YWNpbmFzX3JpZGdlDQpgYGANCg0KIyMgQm94cGxvdHMNCg0KYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE1fQ0KIElFUFNfQ29tcGxldG9fUmVnaWFvX1NQX3ZhY2luYXNfYm94cGxvdCA9IElFUFNfQ29tcGxldG9fUmVnaWFvX1NQX3ZhY2luYXMgJT4lIA0KICBkcm9wX25hKCkgJT4lIA0KICBnZ3Bsb3QoKSArDQogIGFlcyh4ID0gdmFsb3IsIHkgPSBmY3RfcmV2KGFubyksIGZpbGwgPSBhbm8pICsNCiAgZ2VvbV9ib3hwbG90KG91dGxpZXJzID0gRikgKw0KICBnZW9tX2ppdHRlcihhZXMobGFiZWwgPSBub19yZWdpYW8sIGNvbG9yID0gdmFsb3IpLA0KICAgICAgICAgICAgICBhbHBoYSA9IDAuMiwNCiAgICAgICAgICAgICAgbmEucm0gPSBUKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbG9yUmFtcFBhbGV0dGUoYygiIzY1QURDMiIsICJwdXJwbGUiKSkoMTUpKSArDQogIGZhY2V0X3dyYXAodmFycyhub21lX2Rvc19pbmRpY2Fkb3JlcykpICArDQogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjUpLA0KICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksDQogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBwYW5lbC5zcGFjaW5nPXVuaXQoMiwgImxpbmVzIikpICsNCiAgbGFicyh0aXRsZSA9ICJDb2JlcnR1cmEgdmFjaW5hbCIsDQogICAgICAgc3VidGl0bGUgPSAiUGVyw61vZG8gZGUgMjAxMCBhIDIwMjIiLA0KICAgICAgIGNhcHRpb24gPSAiRm9udGU6IElFUFMsIFBOSSwgVGFiTmV0L0RBVEFTVVMiLA0KICAgICAgIHkgPSAiIiwNCiAgICAgICB4ID0gIkNvYmVydHVyYSB2YWNpbmFsICglKSIpICsNCiAgICBmYWNldF93cmFwKH5ub21lX2Rvc19pbmRpY2Fkb3Jlcywgc2NhbGVzID0gImZyZWVfeCIsIG5yb3cgPSAyKQ0KSUVQU19Db21wbGV0b19SZWdpYW9fU1BfdmFjaW5hc19ib3hwbG90ICU+JSANCiAgICBnZ3NhdmUoZmlsZSA9IGhlcmUoIkZpZ3VyYXMiLCAidmFjaW5hc19yZWdpb2VzX2VzdGFkb19zcF8yMDEwXzIwMjJfYm94cGxvdC5wbmciKSwgd2lkdGggPSAxNSwgaGVpZ2h0ID0gMTIpDQoNCklFUFNfQ29tcGxldG9fUmVnaWFvX1NQX3ZhY2luYXNfYm94cGxvdCAgDQpgYGANCg0KYGBge3J9DQpJRVBTX0NvbXBsZXRvX1JlZ2lhb19TUF92YWNpbmFzX0JDR19ib3hwbG90ID0gSUVQU19Db21wbGV0b19SZWdpYW9fU1BfdmFjaW5hcyAlPiUgDQogIGZpbHRlcihub21lX2Rvc19pbmRpY2Fkb3JlcyA9PSAiQkNHIikgJT4lIA0KICBkcm9wX25hKCkgJT4lIA0KICBnZ3Bsb3QoKSArDQogIGFlcyh4ID0gZmN0X3Jldihhbm8pLCB5ID0gdmFsb3IsIGZpbGwgPSBhbm8pICsNCiAgZ2VvbV9ib3hwbG90KG91dGxpZXJzID0gRikgKw0KICBnZW9tX2ppdHRlcihhZXMobGFiZWwgPSBub19yZWdpYW8sIGNvbG9yID0gdmFsb3IpLA0KICAgICAgICAgICAgICBhbHBoYSA9IDAuMiwNCiAgICAgICAgICAgICAgbmEucm0gPSBUKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGNvbG9yUmFtcFBhbGV0dGUoYygiIzY1QURDMiIsICJwdXJwbGUiKSkoMTUpKSArDQogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMiwgY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChzaXplID0gMTApLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksDQogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGZhY2UgPSAiYm9sZCIpLA0KICAgICAgICBwYW5lbC5zcGFjaW5nPXVuaXQoMiwgImxpbmVzIikpICsNCiAgbGFicyh0aXRsZSA9ICJDb2JlcnR1cmEgdmFjaW5hbCAtIEJDRyIsDQogICAgICAgc3VidGl0bGUgPSAiUGVyw61vZG8gZGUgMjAxMCBhIDIwMjIiLA0KICAgICAgIGNhcHRpb24gPSAiRm9udGU6IElFUFMsIFBOSSwgVGFiTmV0L0RBVEFTVVMiLA0KICAgICAgIHkgPSAiIiwNCiAgICAgICB4ID0gIkNvYmVydHVyYSB2YWNpbmFsICglKSIpICANCg0KZ2dwbG90bHkoSUVQU19Db21wbGV0b19SZWdpYW9fU1BfdmFjaW5hc19CQ0dfYm94cGxvdCkNCmBgYA0KDQojIyBHcsOhZmljbyBkZSBsaW5oYXMNCg0KYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE1fQ0KcmVnaW9lc19hY2ltYV85MF92YWNpbmFfbGluaGFzID0gSUVQU19Db21wbGV0b19SZWdpYW9fU1AgJT4lIA0KICBmaWx0ZXIoc3RyX2RldGVjdChub21lX2Rvc19pbmRpY2Fkb3JlcywgIkNvYmVydHVyYSBWYWNpbmFsIiksDQogICAgICAgICBub19yZWdpYW8gJWluJSB1bmlxdWUocmVnaW9lc19hY2ltYV85MCRub19yZWdpYW8pKSAlPiUgDQogIHNlbGVjdChhbm8sIHJlZ2lhbywgbm9fcmVnaWFvLCBub21lX2Rvc19pbmRpY2Fkb3JlcywgdmFsb3IpICU+JSANCiAgbXV0YXRlKHZhbG9yID0gcm91bmQodmFsb3IsIDIpLA0KICAgICAgICAgbm9tZV9kb3NfaW5kaWNhZG9yZXMgPSBzdHJfcmVwbGFjZShub21lX2Rvc19pbmRpY2Fkb3JlcywgIkNvYmVydHVyYSBWYWNpbmFsIGRlICIsICIiKSwNCiAgICAgICAgIG5vbWVfZG9zX2luZGljYWRvcmVzID0gc3RyX3JlcGxhY2Uobm9tZV9kb3NfaW5kaWNhZG9yZXMsICIgXFwoXFwlXFwpIiwgIiIpKSAlPiUgDQogIGRyb3BfbmEoKSAlPiUgDQogIGdncGxvdCgpICsNCiAgYWVzKHggPSBhbm8sIHkgPSB2YWxvciwgZ3JvdXAgPSBub19yZWdpYW8pICsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvciA9IG5vX3JlZ2lhbyksDQogICAgICAgICAgICBzaXplID0gMikgKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiMSB5ZWFyIiwgZGF0ZV9sYWJlbHMgPSAiJXkiKSArDQogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksDQogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgICAgIHBsb3QubWFyZ2luID0gdW5pdChjKDEsMSwxLDEpLCAiY20iKSwNCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgZmFjZSA9ICJwbGFpbiIpKSAgKw0KICBsYWJzKHRpdGxlID0gIkNvYmVydHVyYSB2YWNpbmFsIG5vIGVzdGFkbyBkZSBTw6NvIFBhdWxvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJQZXLDrW9kbyBkZSAyMDEwIGEgMjAyMiIsDQogICAgICAgY2FwdGlvbiA9ICJGb250ZTogSUVQUywgUE5JLCBUYWJOZXQvREFUQVNVUyIsDQogICAgICAgY29sb3IgPSAiTWljcm9ycmVnacOjbyIsDQogICAgICAgeSA9ICJDb2JlcnR1cmEgdmFjaW5hbCAoJSkiLA0KICAgICAgIHggPSAiIikgKw0KICBmYWNldF93cmFwKH5ub21lX2Rvc19pbmRpY2Fkb3Jlcywgc2NhbGVzID0gImZyZWUiKSArDQogIHNjYWxlX3NoYXBlX21hbnVhbCh2YWx1ZXMgPSBjKDE2KSkgKw0KICBzY2FsZV9jb2xvcl9jb3NtaWMoKQ0KDQpyZWdpb2VzX2FjaW1hXzkwX3ZhY2luYV9saW5oYXMNCnJlZ2lvZXNfYWNpbWFfOTBfdmFjaW5hX2xpbmhhcyAlPiUgDQogICAgZ2dzYXZlKGZpbGUgPSBoZXJlKCJGaWd1cmFzIiwgInZhY2luYXNfYWNpbWFfOTBfcmVnaW9lc19lc3RhZG9fc3BfMjAxMF8yMDIyX2xpbmhhcy5wbmciKSwgd2lkdGggPSAxNSwgaGVpZ2h0ID0gMTApDQoNCmBgYA0KDQpgYGB7ciBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD0xMH0NCmJjZ19xdWVkYV8yMDE2X2xpbmhhcyA9IElFUFNfQ29tcGxldG9fUmVnaWFvX1NQICU+JSANCiAgZmlsdGVyKHN0cl9kZXRlY3Qobm9tZV9kb3NfaW5kaWNhZG9yZXMsICJDb2JlcnR1cmEgVmFjaW5hbCIpLA0KICAgICAgICAgc3RyX2RldGVjdChub21lX2Rvc19pbmRpY2Fkb3JlcywgIkJDRyIpLA0KICAgICAgICAgbm9fcmVnaWFvICVpbiUgYmNnX3RvcDVfcmVkdXpfMjAxNiRub19yZWdpYW8pICU+JSANCiAgc2VsZWN0KGFubywgcmVnaWFvLCBub19yZWdpYW8sIG5vbWVfZG9zX2luZGljYWRvcmVzLCB2YWxvcikgJT4lIA0KICBtdXRhdGUodmFsb3IgPSByb3VuZCh2YWxvciwgMiksDQogICAgICAgICBub21lX2Rvc19pbmRpY2Fkb3JlcyA9IHN0cl9yZXBsYWNlKG5vbWVfZG9zX2luZGljYWRvcmVzLCAiQ29iZXJ0dXJhIFZhY2luYWwgZGUgIiwgIiIpLA0KICAgICAgICAgbm9tZV9kb3NfaW5kaWNhZG9yZXMgPSBzdHJfcmVwbGFjZShub21lX2Rvc19pbmRpY2Fkb3JlcywgIiBcXChcXCVcXCkiLCAiIikpICU+JSANCiAgZHJvcF9uYSgpICU+JSANCiAgZ2dwbG90KCkgKw0KICBhZXMoeCA9IGFubywgeSA9IHZhbG9yLCBncm91cCA9IG5vX3JlZ2lhbykgKw0KICBnZW9tX2xpbmUoYWVzKGNvbG9yID0gbm9fcmVnaWFvKSwNCiAgICAgICAgICAgIHNpemUgPSAyKSArDQogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICIxIHllYXIiLCBkYXRlX2xhYmVscyA9ICIleSIpICsNCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjUpLA0KICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGZhY2UgPSAicGxhaW4iKSkgICsNCiAgbGFicyh0aXRsZSA9ICJDb2JlcnR1cmEgdmFjaW5hbCBkYSBCQ0cgbm8gZXN0YWRvIGRlIFPDo28gUGF1bG8iLA0KICAgICAgIHN1YnRpdGxlID0gIlBlcsOtb2RvIGRlIDIwMTAgYSAyMDIyIiwNCiAgICAgICBjYXB0aW9uID0gIkZvbnRlOiBJRVBTLCBQTkksIFRhYk5ldC9EQVRBU1VTIiwNCiAgICAgICBjb2xvciA9ICJNaWNyb3JyZWdpw6NvIiwNCiAgICAgICB5ID0gIkNvYmVydHVyYSB2YWNpbmFsICglKSIsDQogICAgICAgeCA9ICIiKSArDQogIHNjYWxlX2NvbG9yX2Nvc21pYygpDQpiY2dfcXVlZGFfMjAxNl9saW5oYXMNCg0KYmNnX3F1ZWRhXzIwMTZfbGluaGFzICU+JSANCiAgICBnZ3NhdmUoZmlsZSA9IGhlcmUoIkZpZ3VyYXMiLCAidmFjaW5hc19xdWVkYV8yMDE2X3JlZ2lvZXNfZXN0YWRvX3NwXzIwMTBfMjAyMl9saW5oYXMucG5nIiksIHdpZHRoID0gMTAsIGhlaWdodCA9IDUpDQoNCmBgYA0KDQoyMDIwDQoNCmBgYHtyIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTEwfQ0KYmNnX3F1ZWRhXzIwMjBfbGluaGFzID0gSUVQU19Db21wbGV0b19SZWdpYW9fU1AgJT4lIA0KICBmaWx0ZXIoc3RyX2RldGVjdChub21lX2Rvc19pbmRpY2Fkb3JlcywgIkNvYmVydHVyYSBWYWNpbmFsIiksDQogICAgICAgICBzdHJfZGV0ZWN0KG5vbWVfZG9zX2luZGljYWRvcmVzLCAiQkNHIiksDQogICAgICAgICBub19yZWdpYW8gJWluJSBiY2dfdG9wNV9yZWR1el8yMDIwJG5vX3JlZ2lhbykgJT4lIA0KICBzZWxlY3QoYW5vLCByZWdpYW8sIG5vX3JlZ2lhbywgbm9tZV9kb3NfaW5kaWNhZG9yZXMsIHZhbG9yKSAlPiUgDQogIG11dGF0ZSh2YWxvciA9IHJvdW5kKHZhbG9yLCAyKSwNCiAgICAgICAgIG5vbWVfZG9zX2luZGljYWRvcmVzID0gc3RyX3JlcGxhY2Uobm9tZV9kb3NfaW5kaWNhZG9yZXMsICJDb2JlcnR1cmEgVmFjaW5hbCBkZSAiLCAiIiksDQogICAgICAgICBub21lX2Rvc19pbmRpY2Fkb3JlcyA9IHN0cl9yZXBsYWNlKG5vbWVfZG9zX2luZGljYWRvcmVzLCAiIFxcKFxcJVxcKSIsICIiKSkgJT4lIA0KICBkcm9wX25hKCkgJT4lIA0KICBnZ3Bsb3QoKSArDQogIGFlcyh4ID0gYW5vLCB5ID0gdmFsb3IsIGdyb3VwID0gbm9fcmVnaWFvKSArDQogIGdlb21fbGluZShhZXMoY29sb3IgPSBub19yZWdpYW8pLA0KICAgICAgICAgICAgc2l6ZSA9IDIpICsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjEgeWVhciIsIGRhdGVfbGFiZWxzID0gIiV5IikgKw0KICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksDQogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgICAgIHBsb3QubWFyZ2luID0gdW5pdChjKDEsMSwxLDEpLCAiY20iKSwNCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgZmFjZSA9ICJwbGFpbiIpKSAgKw0KICBsYWJzKHRpdGxlID0gIkNvYmVydHVyYSB2YWNpbmFsIGRhIEJDRyBubyBlc3RhZG8gZGUgU8OjbyBQYXVsbyIsDQogICAgICAgc3VidGl0bGUgPSAiUGVyw61vZG8gZGUgMjAxMCBhIDIwMjIiLA0KICAgICAgIGNhcHRpb24gPSAiRm9udGU6IElFUFMsIFBOSSwgVGFiTmV0L0RBVEFTVVMiLA0KICAgICAgIGNvbG9yID0gIk1pY3JvcnJlZ2nDo28iLA0KICAgICAgIHkgPSAiQ29iZXJ0dXJhIHZhY2luYWwgKCUpIiwNCiAgICAgICB4ID0gIiIpICsNCiAgc2NhbGVfY29sb3JfY29zbWljKCkNCmJjZ19xdWVkYV8yMDIwX2xpbmhhcw0KDQpiY2dfcXVlZGFfMjAyMF9saW5oYXMgJT4lIA0KICAgIGdnc2F2ZShmaWxlID0gaGVyZSgiRmlndXJhcyIsICJ2YWNpbmFzX3F1ZWRhXzIwMjBfcmVnaW9lc19lc3RhZG9fc3BfMjAxMF8yMDIyX2xpbmhhcy5wbmciKSwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNSkNCmBgYA0KDQojQW7DoWxpc2UgcG9yIG11bmljaXBpbw0KDQojIyBEZW5zaWRhZGUNCg0KYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTE1fQ0KSUVQU19Db21wbGV0b19NdW5pY2lwaW9fU1BfdmFjaW5hc19yaWRnZSA9IElFUFNfQ29tcGxldG9fTXVuaWNpcGlvX1NQICU+JSANCiAgZmlsdGVyKHN0cl9kZXRlY3QodmFyaWF2ZWwsICJjb2JfdmFjXyIpKSAlPiUgDQogIG11dGF0ZShub21lX2Rvc19pbmRpY2Fkb3JlcyA9IHN0cl9yZXBsYWNlKG5vbWVfZG9zX2luZGljYWRvcmVzLCAiQ29iZXJ0dXJhIFZhY2luYWwgZGUgIiwgIiIpKSAlPiUgDQogIGRyb3BfbmEodmFsb3IpICU+JSANCiAgbXV0YXRlKGFubyA9IGFzLmNoYXJhY3Rlcihhbm8pKSAlPiUgDQogIGdncGxvdCgpICsNCiAgYWVzKHggPSB2YWxvciwgeSA9IGZjdF9yZXYoYW5vKSwgZmlsbCA9IGFubykgKw0KICBnZW9tX2RlbnNpdHlfcmlkZ2VzKHN0YXQgPSAiYmlubGluZSIsIGJpbnMgPSAxMCkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvclJhbXBQYWxldHRlKGMoIiM2NUFEQzIiLCAicHVycGxlIikpKDE1KSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksDQogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgICAgIHBsb3QubWFyZ2luID0gdW5pdChjKDEsMSwxLDEpLCAiY20iKSwNCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgZmFjZSA9ICJib2xkIiksDQogICAgICAgIHBhbmVsLnNwYWNpbmc9dW5pdCgyLCAibGluZXMiKSkgKw0KICBsYWJzKHRpdGxlID0gIkNvYmVydHVyYSB2YWNpbmFsLCBwb3IgbXVuaWPDrXBpbyIsDQogICAgICAgc3VidGl0bGUgPSAiUGVyw61vZG8gZGUgMjAxMCBhIDIwMjIiLA0KICAgICAgIGNhcHRpb24gPSAiRm9udGU6IElFUFMsIFBOSSwgVGFiTmV0L0RBVEFTVVMiLA0KICAgICAgIHkgPSAiIiwNCiAgICAgICB4ID0gIkNvYmVydHVyYSB2YWNpbmFsICglKSIpICsNCiAgICBmYWNldF93cmFwKH5ub21lX2Rvc19pbmRpY2Fkb3Jlcywgc2NhbGVzID0gImZyZWVfeCIsIG5yb3cgPSAxKQ0KICANCklFUFNfQ29tcGxldG9fTXVuaWNpcGlvX1NQX3ZhY2luYXNfcmlkZ2UgJT4lIA0KICAgIGdnc2F2ZShmaWxlID0gaGVyZSgiRmlndXJhcyIsICJWYWNpbmFzX011bmljaXBpb3NfU1BfMjAxMF8yMDIyX2RlbnNpZGFkZS5wbmciKSwgd2lkdGggPSAyMCwgaGVpZ2h0ID0gMTApDQoNCklFUFNfQ29tcGxldG9fTXVuaWNpcGlvX1NQX3ZhY2luYXNfcmlkZ2UNCmBgYA0KDQojIyBCb3hwbG90cw0KDQpgYGB7ciBmaWcuaGVpZ2h0PTEwLCBmaWcud2lkdGg9MTV9DQogSUVQU19Db21wbGV0b19NdW5pY2lwaW9fU1BfdmFjaW5hc19ib3hwbG90ID0gSUVQU19Db21wbGV0b19NdW5pY2lwaW9fU1AgJT4lIA0KICBmaWx0ZXIoc3RyX2RldGVjdCh2YXJpYXZlbCwgImNvYl92YWNfIikpICU+JSANCiAgZHJvcF9uYSgpICU+JSANCiAgICBtdXRhdGUoYW5vID0gYXMuY2hhcmFjdGVyKGFubykpICU+JSANCiAgZ2dwbG90KCkgKw0KICBhZXMoeCA9IHZhbG9yLCB5ID0gZmN0X3Jldihhbm8pLCBmaWxsID0gYW5vKSArDQogIGdlb21faml0dGVyKGFlcyhsYWJlbCA9IG5vX3JlZ2lhbywgY29sb3IgPSB2YWxvciksDQogICAgICAgICAgICAgIGFscGhhID0gMC4yLA0KICAgICAgICAgICAgICBuYS5ybSA9IFQpICsNCiAgZ2VvbV9ib3hwbG90KG91dGxpZXJzID0gRikgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvclJhbXBQYWxldHRlKGMoIiM2NUFEQzIiLCAicHVycGxlIikpKDE1KSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksDQogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgICAgIHBsb3QubWFyZ2luID0gdW5pdChjKDEsMSwxLDEpLCAiY20iKSwNCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgZmFjZSA9ICJib2xkIiksDQogICAgICAgIHBhbmVsLnNwYWNpbmc9dW5pdCgyLCAibGluZXMiKSkgKw0KICBsYWJzKHRpdGxlID0gIkNvYmVydHVyYSB2YWNpbmFsLCBwb3IgbXVuaWNpcGlvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJQZXLDrW9kbyBkZSAyMDEwIGEgMjAyMiIsDQogICAgICAgY2FwdGlvbiA9ICJGb250ZTogSUVQUywgUE5JLCBUYWJOZXQvREFUQVNVUyIsDQogICAgICAgeSA9ICIiLA0KICAgICAgIHggPSAiQ29iZXJ0dXJhIHZhY2luYWwgKCUpIikgKw0KICAgIGZhY2V0X3dyYXAofm5vbWVfZG9zX2luZGljYWRvcmVzLCBzY2FsZXMgPSAiZnJlZV94IiwgbnJvdyA9IDIpDQoNCg0KSUVQU19Db21wbGV0b19NdW5pY2lwaW9fU1BfdmFjaW5hc19ib3hwbG90ICU+JSANCiAgICBnZ3NhdmUoZmlsZSA9IGhlcmUoIkZpZ3VyYXMiLCAiVmFjaW5hc19NdW5pY2lwaW9zX1NQXzIwMTBfMjAyMl9ib3hwbG90LnBuZyIpLCB3aWR0aCA9IDIwLCBoZWlnaHQgPSAxMikNCg0KSUVQU19Db21wbGV0b19NdW5pY2lwaW9fU1BfdmFjaW5hc19ib3hwbG90ICANCmBgYA0KDQpCb3hwbG90IGludGVyYXRpdm8NCmBgYHtyfQ0KSUVQU19Db21wbGV0b19SZWdpYW9fU1BfdmFjaW5hc19CQ0dfYm94cGxvdCA9IElFUFNfQ29tcGxldG9fUmVnaWFvX1NQX3ZhY2luYXMgJT4lIA0KICBmaWx0ZXIobm9tZV9kb3NfaW5kaWNhZG9yZXMgPT0gIkJDRyIpICU+JSANCiAgZHJvcF9uYSgpICU+JSANCiAgZ2dwbG90KCkgKw0KICBhZXMoeCA9IGZjdF9yZXYoYW5vKSwgeSA9IHZhbG9yLCBmaWxsID0gYW5vKSArDQogIGdlb21fYm94cGxvdChvdXRsaWVycyA9IEYpICsNCiAgZ2VvbV9qaXR0ZXIoYWVzKGxhYmVsID0gbm9fcmVnaWFvLCBjb2xvciA9IHZhbG9yKSwNCiAgICAgICAgICAgICAgYWxwaGEgPSAwLjIsDQogICAgICAgICAgICAgIG5hLnJtID0gVCkgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvclJhbXBQYWxldHRlKGMoIiM2NUFEQzIiLCAicHVycGxlIikpKDE1KSkgKw0KICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTIsIGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSwNCiAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMSwxLDEsMSksICJjbSIpLA0KICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwLCBmYWNlID0gImJvbGQiKSwNCiAgICAgICAgcGFuZWwuc3BhY2luZz11bml0KDIsICJsaW5lcyIpKSArDQogIGxhYnModGl0bGUgPSAiQ29iZXJ0dXJhIHZhY2luYWwgLSBCQ0ciLA0KICAgICAgIHN1YnRpdGxlID0gIlBlcsOtb2RvIGRlIDIwMTAgYSAyMDIyIiwNCiAgICAgICBjYXB0aW9uID0gIkZvbnRlOiBJRVBTLCBQTkksIFRhYk5ldC9EQVRBU1VTIiwNCiAgICAgICB5ID0gIiIsDQogICAgICAgeCA9ICJDb2JlcnR1cmEgdmFjaW5hbCAoJSkiKSAgDQoNCmdncGxvdGx5KElFUFNfQ29tcGxldG9fUmVnaWFvX1NQX3ZhY2luYXNfQkNHX2JveHBsb3QpDQpgYGANCg0KIyMgR3LDoWZpY28gZGUgbGluaGFzDQoNCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xNX0NCnJlZ2lvZXNfYWNpbWFfOTBfdmFjaW5hX2xpbmhhcyA9IElFUFNfQ29tcGxldG9fUmVnaWFvX1NQICU+JSANCiAgZmlsdGVyKHN0cl9kZXRlY3Qobm9tZV9kb3NfaW5kaWNhZG9yZXMsICJDb2JlcnR1cmEgVmFjaW5hbCIpLA0KICAgICAgICAgbm9fcmVnaWFvICVpbiUgdW5pcXVlKHJlZ2lvZXNfYWNpbWFfOTAkbm9fcmVnaWFvKSkgJT4lIA0KICBzZWxlY3QoYW5vLCByZWdpYW8sIG5vX3JlZ2lhbywgbm9tZV9kb3NfaW5kaWNhZG9yZXMsIHZhbG9yKSAlPiUgDQogIG11dGF0ZSh2YWxvciA9IHJvdW5kKHZhbG9yLCAyKSwNCiAgICAgICAgIG5vbWVfZG9zX2luZGljYWRvcmVzID0gc3RyX3JlcGxhY2Uobm9tZV9kb3NfaW5kaWNhZG9yZXMsICJDb2JlcnR1cmEgVmFjaW5hbCBkZSAiLCAiIiksDQogICAgICAgICBub21lX2Rvc19pbmRpY2Fkb3JlcyA9IHN0cl9yZXBsYWNlKG5vbWVfZG9zX2luZGljYWRvcmVzLCAiIFxcKFxcJVxcKSIsICIiKSkgJT4lIA0KICBkcm9wX25hKCkgJT4lIA0KICBnZ3Bsb3QoKSArDQogIGFlcyh4ID0gYW5vLCB5ID0gdmFsb3IsIGdyb3VwID0gbm9fcmVnaWFvKSArDQogIGdlb21fbGluZShhZXMoY29sb3IgPSBub19yZWdpYW8pLA0KICAgICAgICAgICAgc2l6ZSA9IDIpICsNCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjEgeWVhciIsIGRhdGVfbGFiZWxzID0gIiV5IikgKw0KICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjUpLA0KICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGZhY2UgPSAicGxhaW4iKSkgICsNCiAgbGFicyh0aXRsZSA9ICJDb2JlcnR1cmEgdmFjaW5hbCBubyBlc3RhZG8gZGUgU8OjbyBQYXVsbyIsDQogICAgICAgc3VidGl0bGUgPSAiUGVyw61vZG8gZGUgMjAxMCBhIDIwMjIiLA0KICAgICAgIGNhcHRpb24gPSAiRm9udGU6IElFUFMsIFBOSSwgVGFiTmV0L0RBVEFTVVMiLA0KICAgICAgIGNvbG9yID0gIk1pY3JvcnJlZ2nDo28iLA0KICAgICAgIHkgPSAiQ29iZXJ0dXJhIHZhY2luYWwgKCUpIiwNCiAgICAgICB4ID0gIiIpICsNCiAgZmFjZXRfd3JhcCh+bm9tZV9kb3NfaW5kaWNhZG9yZXMsIHNjYWxlcyA9ICJmcmVlIikgKw0KICBzY2FsZV9zaGFwZV9tYW51YWwodmFsdWVzID0gYygxNikpICsNCiAgc2NhbGVfY29sb3JfY29zbWljKCkNCg0KcmVnaW9lc19hY2ltYV85MF92YWNpbmFfbGluaGFzDQpyZWdpb2VzX2FjaW1hXzkwX3ZhY2luYV9saW5oYXMgJT4lIA0KICAgIGdnc2F2ZShmaWxlID0gaGVyZSgiRmlndXJhcyIsICJ2YWNpbmFzX2FjaW1hXzkwX3JlZ2lvZXNfZXN0YWRvX3NwXzIwMTBfMjAyMl9saW5oYXMucG5nIiksIHdpZHRoID0gMTUsIGhlaWdodCA9IDEwKQ0KDQpgYGANCg0KYGBge3IgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9MTB9DQpiY2dfcXVlZGFfMjAxNl9saW5oYXMgPSBJRVBTX0NvbXBsZXRvX1JlZ2lhb19TUCAlPiUgDQogIGZpbHRlcihzdHJfZGV0ZWN0KG5vbWVfZG9zX2luZGljYWRvcmVzLCAiQ29iZXJ0dXJhIFZhY2luYWwiKSwNCiAgICAgICAgIHN0cl9kZXRlY3Qobm9tZV9kb3NfaW5kaWNhZG9yZXMsICJCQ0ciKSwNCiAgICAgICAgIG5vX3JlZ2lhbyAlaW4lIGJjZ190b3A1X3JlZHV6XzIwMTYkbm9fcmVnaWFvKSAlPiUgDQogIHNlbGVjdChhbm8sIHJlZ2lhbywgbm9fcmVnaWFvLCBub21lX2Rvc19pbmRpY2Fkb3JlcywgdmFsb3IpICU+JSANCiAgbXV0YXRlKHZhbG9yID0gcm91bmQodmFsb3IsIDIpLA0KICAgICAgICAgbm9tZV9kb3NfaW5kaWNhZG9yZXMgPSBzdHJfcmVwbGFjZShub21lX2Rvc19pbmRpY2Fkb3JlcywgIkNvYmVydHVyYSBWYWNpbmFsIGRlICIsICIiKSwNCiAgICAgICAgIG5vbWVfZG9zX2luZGljYWRvcmVzID0gc3RyX3JlcGxhY2Uobm9tZV9kb3NfaW5kaWNhZG9yZXMsICIgXFwoXFwlXFwpIiwgIiIpKSAlPiUgDQogIGRyb3BfbmEoKSAlPiUgDQogIGdncGxvdCgpICsNCiAgYWVzKHggPSBhbm8sIHkgPSB2YWxvciwgZ3JvdXAgPSBub19yZWdpYW8pICsNCiAgZ2VvbV9saW5lKGFlcyhjb2xvciA9IG5vX3JlZ2lhbyksDQogICAgICAgICAgICBzaXplID0gMikgKw0KICBzY2FsZV94X2RhdGUoZGF0ZV9icmVha3MgPSAiMSB5ZWFyIiwgZGF0ZV9sYWJlbHMgPSAiJXkiKSArDQogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwNCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMSwxLDEsMSksICJjbSIpLA0KICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBmYWNlID0gInBsYWluIikpICArDQogIGxhYnModGl0bGUgPSAiQ29iZXJ0dXJhIHZhY2luYWwgZGEgQkNHIG5vIGVzdGFkbyBkZSBTw6NvIFBhdWxvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJQZXLDrW9kbyBkZSAyMDEwIGEgMjAyMiIsDQogICAgICAgY2FwdGlvbiA9ICJGb250ZTogSUVQUywgUE5JLCBUYWJOZXQvREFUQVNVUyIsDQogICAgICAgY29sb3IgPSAiTWljcm9ycmVnacOjbyIsDQogICAgICAgeSA9ICJDb2JlcnR1cmEgdmFjaW5hbCAoJSkiLA0KICAgICAgIHggPSAiIikgKw0KICBzY2FsZV9jb2xvcl9jb3NtaWMoKQ0KYmNnX3F1ZWRhXzIwMTZfbGluaGFzDQoNCmJjZ19xdWVkYV8yMDE2X2xpbmhhcyAlPiUgDQogICAgZ2dzYXZlKGZpbGUgPSBoZXJlKCJGaWd1cmFzIiwgInZhY2luYXNfcXVlZGFfMjAxNl9yZWdpb2VzX2VzdGFkb19zcF8yMDEwXzIwMjJfbGluaGFzLnBuZyIpLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA1KQ0KDQpgYGANCg0KMjAyMA0KDQpgYGB7ciBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD0xMH0NCmJjZ19xdWVkYV8yMDIwX2xpbmhhcyA9IElFUFNfQ29tcGxldG9fUmVnaWFvX1NQICU+JSANCiAgZmlsdGVyKHN0cl9kZXRlY3Qobm9tZV9kb3NfaW5kaWNhZG9yZXMsICJDb2JlcnR1cmEgVmFjaW5hbCIpLA0KICAgICAgICAgc3RyX2RldGVjdChub21lX2Rvc19pbmRpY2Fkb3JlcywgIkJDRyIpLA0KICAgICAgICAgbm9fcmVnaWFvICVpbiUgYmNnX3RvcDVfcmVkdXpfMjAyMCRub19yZWdpYW8pICU+JSANCiAgc2VsZWN0KGFubywgcmVnaWFvLCBub19yZWdpYW8sIG5vbWVfZG9zX2luZGljYWRvcmVzLCB2YWxvcikgJT4lIA0KICBtdXRhdGUodmFsb3IgPSByb3VuZCh2YWxvciwgMiksDQogICAgICAgICBub21lX2Rvc19pbmRpY2Fkb3JlcyA9IHN0cl9yZXBsYWNlKG5vbWVfZG9zX2luZGljYWRvcmVzLCAiQ29iZXJ0dXJhIFZhY2luYWwgZGUgIiwgIiIpLA0KICAgICAgICAgbm9tZV9kb3NfaW5kaWNhZG9yZXMgPSBzdHJfcmVwbGFjZShub21lX2Rvc19pbmRpY2Fkb3JlcywgIiBcXChcXCVcXCkiLCAiIikpICU+JSANCiAgZHJvcF9uYSgpICU+JSANCiAgZ2dwbG90KCkgKw0KICBhZXMoeCA9IGFubywgeSA9IHZhbG9yLCBncm91cCA9IG5vX3JlZ2lhbykgKw0KICBnZW9tX2xpbmUoYWVzKGNvbG9yID0gbm9fcmVnaWFvKSwNCiAgICAgICAgICAgIHNpemUgPSAyKSArDQogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICIxIHllYXIiLCBkYXRlX2xhYmVscyA9ICIleSIpICsNCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjUpLA0KICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGZhY2UgPSAicGxhaW4iKSkgICsNCiAgbGFicyh0aXRsZSA9ICJDb2JlcnR1cmEgdmFjaW5hbCBkYSBCQ0cgbm8gZXN0YWRvIGRlIFPDo28gUGF1bG8iLA0KICAgICAgIHN1YnRpdGxlID0gIlBlcsOtb2RvIGRlIDIwMTAgYSAyMDIyIiwNCiAgICAgICBjYXB0aW9uID0gIkZvbnRlOiBJRVBTLCBQTkksIFRhYk5ldC9EQVRBU1VTIiwNCiAgICAgICBjb2xvciA9ICJNaWNyb3JyZWdpw6NvIiwNCiAgICAgICB5ID0gIkNvYmVydHVyYSB2YWNpbmFsICglKSIsDQogICAgICAgeCA9ICIiKSArDQogIHNjYWxlX2NvbG9yX2Nvc21pYygpDQpiY2dfcXVlZGFfMjAyMF9saW5oYXMNCg0KYmNnX3F1ZWRhXzIwMjBfbGluaGFzICU+JSANCiAgICBnZ3NhdmUoZmlsZSA9IGhlcmUoIkZpZ3VyYXMiLCAidmFjaW5hc19xdWVkYV8yMDIwX3JlZ2lvZXNfZXN0YWRvX3NwXzIwMTBfMjAyMl9saW5oYXMucG5nIiksIHdpZHRoID0gMTAsIGhlaWdodCA9IDUpDQpgYGANCg0KDQoNCg0KDQoNCg0KIyBQQ0ENCiMgTWljcm9ycmVnacOjbw0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShnZ3JlcGVsKSAjbG9hZCBiZWZvcmUgZmFjdG9leHRyYQ0KbGlicmFyeShmYWN0b2V4dHJhKQ0KbGlicmFyeShjYXJldCkNCmxpYnJhcnkoc3RhdHMpDQpsaWJyYXJ5KGdnZm9ydGlmeSkNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoY29ycnBsb3QpDQpsaWJyYXJ5KGNvd3Bsb3QpDQpsaWJyYXJ5KGdnY29ycnBsb3QpDQpsaWJyYXJ5KENvbXBsZXhIZWF0bWFwKQ0KbGlicmFyeShjaXJjbGl6ZSkNCmxpYnJhcnkoZ2dFeHRyYSkNCmxpYnJhcnkoRmFjdG9NaW5lUikNCmBgYA0KDQoNCiMjIE1pY3JvcnJlZ2nDo286IFNlbGVjaW9uYWRvcw0KDQpgYGB7cn0NCiNJbXB1dHMNCmFub19zZWxlYyA9ICIyMDIwIg0KYW5vX3NlbGVjX3ltZCA9IHltZCgiMjAyMC0wMS0wMSIpDQpyb3dfbmFtZXMgPSAibm9fcmVnaWFvIg0Kbml2ZWxfc2VsZWMgPSAiUmVnacOjbyINCg0KIw0KcGNhX2RhZG9zID0gSUVQU19Db21wbGV0b18yMDEwXzIwMjJfc2VsZWNpb25hZG9zX1NQICU+JSANCiAgZmlsdGVyKG5pdmVsID09IG5pdmVsX3NlbGVjLA0KICAgICAgICAgYW5vID09IGFub19zZWxlYykgJT4lDQogIGNvbHVtbl90b19yb3duYW1lcyhyb3dfbmFtZXMpICU+JSANCiAgc2VsZWN0KGNvYl9hYjpjb2JfdmFjX3BlbnRhLCANCiAgICAgICAgIHR4X21vcnRfYWpfY2VuczpwY3RfZGVzcF9yZWNwX3NhdWRlX211biwgDQogICAgICAgICBkZXNwX3RvdF9zYXVkZV9wY19tdW5fZGVmLA0KICAgICAgICAgZGVzcF9yZWNwX3NhdWRlX3BjX211bl9kZWYsIA0KICAgICAgICAgaWRlYl81YW5vOnBvcCwgDQogICAgICAgICBwY3RfcG9wX2ZlbTpwY3RfcG9wX21hc2MpDQoNCnBjYV9kYWRvc19tYXRyaXggPSBwY2FfZGFkb3MgJT4lIA0KICBhcy5tYXRyaXgoKQ0KDQpkaW0ocGNhX2RhZG9zX21hdHJpeCkNCg0KcGNhX2RhZG9zX2FubiA9IElFUFNfQ29tcGxldG9fMjAxMF8yMDIyX3NlbGVjaW9uYWRvc19TUCAlPiUgDQogIGZpbHRlcihuaXZlbCA9PSBuaXZlbF9zZWxlYywNCiAgICAgICAgIGFubyA9PSBhbm9fc2VsZWMpICU+JSANCiAgc2VsZWN0KHJvd19uYW1lcywgcG9wKSAlPiUgDQogIG11dGF0ZShwb3J0ZV9tdW5pY2lwaW8gPSBjYXNlX3doZW4ocG9wIDw9IDIwMDAwIH4gIlBlcXVlbm8gUG9ydGUgSSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9wIDw9IDUwMDAwIH4gIlBlcXVlbm8gUG9ydGUgSUkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcCA8PSAxMDAwMDAgfiAiTcOpZGlvIFBvcnRlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3AgPD0gOTAwMDAwIH4gIkdyYW5kZSBQb3J0ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+ICJNZXRyw7Nwb2xlIiksDQogICAgICAgICBJRCA9IHJvd19uYW1lcykgJT4lIA0KICBzZWxlY3QoLXBvcCkgJT4lIA0KICAgIGNvbHVtbl90b19yb3duYW1lcyhyb3dfbmFtZXMpDQpgYGANCg0KDQpgYGB7ciBmaWcud2lkdGggPSAxNSwgZmlnLmhlaWdodCA9IDV9DQojIERlbGV0ZSBjb2x1bW5zIHdpdGggbmVhciAwIHZhcmlhbmNlDQpuZWFyWmVyb1ZhckNvbHMgPC0gbmVhclplcm9WYXIocGNhX2RhZG9zX21hdHJpeCwgc2F2ZU1ldHJpY3MgPSBUUlVFKQ0KcGNhX2RhZG9zX21hdHJpeF9wY2EgPC0gcGNhX2RhZG9zX21hdHJpeFssICFuZWFyWmVyb1ZhckNvbHMkbnp2XQ0KcGNhX3JlcyA8LSBwcmNvbXAocGNhX2RhZG9zX21hdHJpeF9wY2EsIHNjYWxlLiA9IFQpDQoNCiNTZWxlY2lvbmFyIHZhcmnDoXZlaXMgZGUgaW50ZXJlc3NlDQpjb3JyX21hdHJpeF9zZWxlYyA9IGNvcnJfbWF0cml4ICU+JSANCiAgYXMuZGF0YS5mcmFtZSgpICU+JSANCiAgcm93bmFtZXNfdG9fY29sdW1uKCJpZCIpICU+JSANCiAgZmlsdGVyKHN0cl9kZXRlY3QoaWQsICJjb2JfdmFjIikpICU+JSANCiAgY29sdW1uX3RvX3Jvd25hbWVzKCJpZCIpICU+JSANCiAgYXMubWF0cml4KCkNCg0KIyBDb3JyZWxhdGlvbiBwbG90IC0tLS0NCmNvcnJfbWF0cml4ID0gY29yKHBjYV9kYWRvc19tYXRyaXhfcGNhICU+JSBzY2FsZSgpKSANCnZhciA8LSBnZXRfcGNhX3ZhcihwY2FfcmVzKQ0KcC5tYXQgPSBjb3JfcG1hdChwY2FfZGFkb3NfbWF0cml4X3BjYSAlPiUgc2NhbGUoKSkNCg0KcC5tYXRfMiA9IGNvcl9wbWF0KGNvcnJfbWF0cml4X3NlbGVjICU+JSBzY2FsZSgpKSAlPiUgDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUgDQogIHJvd25hbWVzX3RvX2NvbHVtbigiaWQiKSAlPiUgDQogIGlubmVyX2pvaW4oY29ycl9tYXRyaXhfc2VsZWMgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCJpZCIpICU+JSBzZWxlY3QoImlkIiksIGJ5ID0gImlkIikgJT4lIA0KICBjb2x1bW5fdG9fcm93bmFtZXMoImlkIikgJT4lIA0KICBhcy5tYXRyaXgoKQ0KDQoNCg0KI1NlbGVjaW9uYWRvcw0KcG5nKGZpbGUgPSBoZXJlKCJGaWd1cmFzIiwgcGFzdGUwKCJQQ0FfIiwgbml2ZWxfc2VsZWMgLCJfIiwgYW5vX3NlbGVjLCAiX1NlbGVjaW9uYWRvc19Db3JycGxvdC5wbmciKSksIA0KICAgIHdpZHRoID0gMTUsIGhlaWdodCA9IDUsDQogICAgdW5pdHMgPSAiaW4iLA0KICAgIHJlcyA9IDMwMCkNCg0KY29ycnBsb3Qocm91bmQoY29ycl9tYXRyaXhfc2VsZWMsIDIpLA0KICAgICAgICAgaXMuY29yciA9IFRSVUUsDQogICAgICAgICB0bC5jb2wgPSAiYmxhY2siLA0KICAgICAgICAgdGl0bGUgPSAiQ29iZXJ0dXJhIHZhY2luYWwgZSBpbmRpY2Fkb3JlcyBzb2NpYWlzLCBlY29ub21pY29zLCBkZW1vZ3LDoWZpY29zIGUgZGUgc2HDumRlIiwNCiAgICAgICAgIGNleC5tYWluID0gMiwNCiAgICAgICAgIG1ldGhvZCA9ICJjb2xvciIsDQogICAgICAgICBwLm1hdCA9IHAubWF0XzIsDQogICAgICAgICB0bC5zcnQgPSA0NSwNCiAgICAgICAgIHNpZy5sZXZlbCA9IGMoMC4wNSksDQogICAgICAgICBtYXI9YygxLDAsNCwwKSwNCiAgICAgICAgIGFkZENvZWYuY29sID0gJ2JsYWNrJywNCiAgICAgICAgIG51bWJlci5jZXggPSAwLjYsDQogICAgICAgICBpbnNpZyA9ICJibGFuayIsDQogICAgICAgICBjb2wgPSBjb2xvclJhbXBQYWxldHRlKGMoIiM2NUFEQzIiLCAid2hpdGUiLCAiI0U4NDY0NiIpKSgxMSkpDQoNCmRldi5vZmYoKQ0KDQoNCmBgYA0KDQoNCmBgYHtyIGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gMTB9DQojVG9kb3MNCmNvcnJwbG90ID0gZ2djb3JycGxvdChjb3JyX21hdHJpeCwNCiAgICAgICAgICAgICAgICAgICAgICBoYy5vcmRlciA9IFRSVUUsDQogICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gImNpcmNsZSIsDQogICAgICAgICAgICAgICAgICAgICAgdHlwZSA9ICJmdWxsIiwNCiAgICAgICAgICAgICAgICAgICAgICBnZ3RoZW1lID0gTlVMTCwNCiAgICAgICAgICAgICAgICAgICAgICBvdXRsaW5lLmNvbCA9ICJ3aGl0ZSIsDQogICAgICAgICAgICAgICAgICAgICAgcC5tYXQgPSBwLm1hdCwNCiAgICAgICAgIGluc2lnID0gImJsYW5rIiwNCg0KICAgICAgICAgICAgICAgICAgICAgIHNpZy5sZXZlbCA9IDAuMDUsDQogICAgICAgICAgICAgICAgICAgICAgY29sb3JzID0gYygiIzY1QURDMiIsICJ3aGl0ZSIsICIjRTg0NjQ2IikpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgc2l6ZSA9IDEwKSwNCiAgICAgICAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEwKSkgKw0KICBsYWJzKHRpdGxlID0gIkNvYmVydHVyYSB2YWNpbmFsIGUgaW5kaWNhZG9yZXMgc29jaWFpcywgZWNvbm9taWNvcywgZGVtb2dyw6FmaWNvcyBlIGRlIHNhw7pkZSIpICsNCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGZhY2UgPSAiYm9sZCIpKQ0KDQpjb3JycGxvdCAlPiUgDQogIGdnc2F2ZShmaWxlID0gaGVyZSgiRmlndXJhcyIsIHBhc3RlMCgiUENBXyIsIG5pdmVsX3NlbGVjICwiXyIsIGFub19zZWxlYywgIl9Ub2Rvc0luZGljYWRvcmVzX0NvcnJwbG90LnBuZyIpKSwgd2lkdGggPSAxNSwgaGVpZ2h0ID0gMTApDQoNCmBgYA0KDQoNCmBgYHtyIGZpZy53aWR0aCA9IDUsIGZpZy5oZWlnaHQgPSA1fQ0KI1BDQSAtLS0tDQpkYXRhLnBjYSA9IHByY29tcChjb3JyX21hdHJpeCkgI1BDQQ0Kc3VtbWFyeShjb3JyX21hdHJpeCkgI1JldG9ybmFyIFBDcw0KDQojU2NyZWUgcGxvdCAtLS0tDQpzY3JlZV9wbG90ID0gZnZpel9laWcoZGF0YS5wY2EsIA0KICAgICAgICAgICAgICAgICAgICAgIGFkZGxhYmVscyA9IFRSVUUsDQogICAgICAgICAgICAgICAgICAgICAgeWxpbSA9IGMoMCwgNzApKSArDQogIGdlb21fY29sKGNvbG9yID0gIiMwMEFGQkIiLCBmaWxsID0gIiMwMEFGQkIiKSANCg0Kc2NyZWVfcGxvdA0KDQpzY3JlZV9wbG90ICU+JSANCiAgZ2dzYXZlKGZpbGUgPSBoZXJlKCJGaWd1cmFzIiwgcGFzdGUwKCJQQ0FfIiwgbml2ZWxfc2VsZWMgLCJfIiwgYW5vX3NlbGVjLCAiX1NjcmVlcGxvdC5wbmciKSksIA0KICAgICAgICAgd2lkdGggPSA1LA0KICAgICAgICAgaGVpZ2h0ID0gMykNCmBgYA0KDQoNCmBgYHtyIGZpZy53aWR0aCA9IDcsIGZpZy5oZWlnaHQgPSA3fQ0KIyBMb2FkaW5ncyBwbG90IC0tLS0NCm9wdGlvbnMoZ2dyZXBlbC5tYXgub3ZlcmxhcHMgPSBJbmYpDQoNCmNpcmNsZV9jb250cmliPSBmdml6X3BjYV92YXIocGNhX3JlcywgY29sLnZhciA9ICJjb3MyIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyYWRpZW50LmNvbHMgPSBjKCIjNjVBREMyIiwgImJsYWNrIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QudmFyPSBsaXN0KGNvczIgPSAzMCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwZWwgPSBULCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsc2l6ZSA9IDQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wuY2lyY2xlID0gTkEpIA0KDQpjaXJjbGVfY29udHJpYg0KDQpjaXJjbGVfY29udHJpYiAlPiUgDQogIGdnc2F2ZShmaWxlID0gaGVyZSgiRmlndXJhcyIsIHBhc3RlMCgiUENBXyIsIG5pdmVsX3NlbGVjICwiXyIsIGFub19zZWxlYywgIl9Mb2FkaW5ncy5wbmciKSksIA0KICAgICAgICAgd2lkdGggPSA1LCANCiAgICAgICAgIGhlaWdodCA9IDUpDQoNCmBgYA0KDQpgYGB7ciBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDZ9DQojIENsdXN0ZXIgLS0tLS0tDQojRGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgY2x1c3RlcnMNCnBjYV9zY29yZXMgPC0gZGF0YS5mcmFtZShwY2FfcmVzJHhbLCAxOjJdKQ0KZnZpel9uYmNsdXN0KHBjYV9zY29yZXMsICANCiAgICAgICAgICAgICAgICAgICAgIEZVTmNsdXN0ZXIgPSBrbWVhbnMsDQogICAgICAgICAgICAgICAgICAgICBtZXRob2QgPSAid3NzIikNCg0KDQpzZXQuc2VlZCg2NjYpICMgU2V0IHNlZWQgZm9yIHJhbmRvbWl6YXRpb24NCmNsdXN0ZXJfbW9kZWwgPC0ga21lYW5zKHBjYV9yZXMkeFssIDE6Ml0sIGNlbnRlcnMgPSAyKSAgI1NldCB0aGUgbnVtYmVyIG9mIGNsdXN0ZXJzDQoNCnBjYV9kYWRvcyRjbHVzdGVyIDwtIGFzLmZhY3RvcihjbHVzdGVyX21vZGVsJGNsdXN0ZXIpDQpwY2FfZGFkb3MgPSBwY2FfZGFkb3MgJT4lIA0KICByb3duYW1lc190b19jb2x1bW4oImlkIikNCmBgYA0KDQoNCmBgYHtyIGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gNn0NCiMgUGxvdCAtLS0tLS0NCnBjYV9wbG90X2tubl9jbHVzdGVyID0gYXV0b3Bsb3QocGNhX3JlcywgDQogICAgICAgIGRhdGEgPSBwY2FfZGFkb3MsIA0KICAgICAgICBjb2xvdXIgPSAnY2x1c3RlcicpICArDQogIHN0YXRfZWxsaXBzZShhZXMoY29sb3IgPSBjbHVzdGVyLCANCiAgICAgICAgICAgICAgICAgICBmaWxsID0gY2x1c3RlciksIA0KICAgICAgICAgICAgICAgZ2VvbSA9ICJwb2x5Z29uIiwgDQogICAgICAgICAgICAgICBhbHBoYSA9IDAuMSwgDQogICAgICAgICAgICAgICBsaW5ldHlwZSA9IDEsDQogICAgICAgICAgICAgICBzaXplID0gMC4zLA0KICAgICAgICAgICAgICAgdHlwZSA9ICJ0IikgKw0KICBnZW9tX3BvaW50KGFlcyhmaWxsID0gY2x1c3RlciwNCiAgICAgICAgICAgICAgICAgc2l6ZSA9IHBvcCksDQogICAgICAgICAgICAgY29sb3VyPSJibGFjayIsDQogICAgICAgICAgICAgcGNoPTIxKSArDQogIGxhYnModGl0bGUgPSBwYXN0ZTAobml2ZWxfc2VsZWMsICJwYXVsaXN0YSwgIiwgYW5vX3NlbGVjKSkgKyANCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIpKSArDQogIGdlb21fbGFiZWxfcmVwZWwoYWVzKGxhYmVsID0gaWQsDQogICAgICAgICAgICAgICAgICAgICAgc2VnbWVudC5jb2xvdXI9ICJibGFjayIpLA0KICAgICAgICAgICAgICAgICAgYm94LnBhZGRpbmcgPSAwLjMsDQogICAgICAgICAgICAgICAgICBzaXplID0gMykgICsNCiAgc2NhbGVfc2l6ZV9jb250aW51b3VzKHJhbmdlID0gYygyLDgpKQ0KcGNhX3Bsb3Rfa25uX2NsdXN0ZXJfbWFyZ2luYWwgPSBnZ01hcmdpbmFsKA0KICBwY2FfcGxvdF9rbm5fY2x1c3RlciwNCiAgZ3JvdXBGaWxsID0gVCwNCiAgZ3JvdXBDb2xvdXIgPSBUKQ0KcGNhX3Bsb3Rfa25uX2NsdXN0ZXJfbWFyZ2luYWwNCg0KcGNhX3Bsb3Rfa25uX2NsdXN0ZXJfbWFyZ2luYWwgJT4lIGdnc2F2ZShmaWxlID0gaGVyZSgiRmlndXJhcyIsIHBhc3RlMCgiUENBXyIsIG5pdmVsX3NlbGVjICwiXyIsIGFub19zZWxlYywgIl9DbHVzdGVycy5wbmciKSksIHdpZHRoID0gMTAsIGhlaWdodCA9IDYpDQoNCmBgYA0KDQpgYGB7ciBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDZ9DQpnZ3RoZW1yKCJmcmVzaCIsIHNwYWNpbmcgPSAxKQ0Kc3dhdGNoKCkNCg0KI1BvbGlvIC0tLS0NCnBjYV9wbG90X2tubl9jbHVzdGVyX2dyYWRpZW50ID0gYXV0b3Bsb3QocGNhX3JlcywgDQogICAgICAgIGRhdGEgPSBwY2FfZGFkb3MpICArDQogIGdlb21fcG9pbnQoYWVzKGZpbGwgPSBjb2JfdmFjX3BvbGlvLA0KICAgICAgICAgICAgICAgICBzaXplID0gcG9wKSwNCiAgICAgICAgICAgICBjb2xvdXI9ImJsYWNrIiwNCiAgICAgICAgICAgICBwY2g9MjEpICsNCiAgbGFicyh0aXRsZSA9IHBhc3RlMChuaXZlbF9zZWxlYywgInBhdWxpc3RhLCAiLCBhbm9fc2VsZWMpKSArIA0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpICArDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gIiNFODQ2NDYiLCBoaWdoID0gIiM2NUFEQzIiKSArDQogICAgc2NhbGVfc2l6ZV9jb250aW51b3VzKHJhbmdlID0gYygyLDgpKQ0KDQoNCnBjYV9wbG90X2tubl9jbHVzdGVyX2dyYWRpZW50DQoNCnBjYV9wbG90X2tubl9jbHVzdGVyX2dyYWRpZW50ICU+JSBnZ3NhdmUoZmlsZSA9ICBoZXJlKCJGaWd1cmFzIiwgcGFzdGUwKCJQQ0FfIiwgbml2ZWxfc2VsZWMgLCJfIiwgYW5vX3NlbGVjLCJfUG9saW8ucG5nIikpLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2KQ0KDQojQkNHIC0tLS0tDQoNCnBjYV9wbG90X2tubl9jbHVzdGVyX2dyYWRpZW50ID0gYXV0b3Bsb3QocGNhX3JlcywgDQogICAgICAgIGRhdGEgPSBwY2FfZGFkb3MpICArDQogIGdlb21fcG9pbnQoYWVzKGZpbGwgPSBjb2JfdmFjX2JjZywNCiAgICAgICAgICAgICAgICAgc2l6ZSA9IHBvcCksDQogICAgICAgICAgICAgY29sb3VyPSJibGFjayIsDQogICAgICAgICAgICAgcGNoPTIxKSArDQogIGxhYnModGl0bGUgPSBwYXN0ZTAobml2ZWxfc2VsZWMsICJwYXVsaXN0YSwgIiwgYW5vX3NlbGVjKSkgKyANCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKSAgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICIjRTg0NjQ2IiwgaGlnaCA9ICIjNjVBREMyIikgKw0KICAgIHNjYWxlX3NpemVfY29udGludW91cyhyYW5nZSA9IGMoMiw4KSkNCg0KDQpwY2FfcGxvdF9rbm5fY2x1c3Rlcl9ncmFkaWVudA0KDQpwY2FfcGxvdF9rbm5fY2x1c3Rlcl9ncmFkaWVudCAlPiUgZ2dzYXZlKGZpbGUgPSAgaGVyZSgiRmlndXJhcyIsIHBhc3RlMCgiUENBXyIsIG5pdmVsX3NlbGVjICwiXyIsIGFub19zZWxlYywiX0JDRy5wbmciKSksIHdpZHRoID0gMTAsIGhlaWdodCA9IDYpDQpgYGANCg0KDQpgYGB7ciBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDZ9DQoiIzExMTExMSIgIiM2NUFEQzIiICIjMjMzQjQzIiAiI0U4NDY0NiIgIiNDMjkzNjUiICIjMzYyQzIxIiAiIzMxNjY3NSIgIiMxNjhFN0YiICIjMTA5QjM3Ig0KcmVzLmttIDwtIGttZWFucyh2YXIkY29vcmQsIGNlbnRlcnMgPSAzLCBuc3RhcnQgPSAyNSkNCmdycCA8LSBhcy5mYWN0b3IocmVzLmttJGNsdXN0ZXIpDQoNCnBjYV9wbG90X2tubl9jbHVzdGVyX2JpcGxvdCA9IGZ2aXpfcGNhX2JpcGxvdChwY2FfcmVzLCANCiAgICAgICAgICAgICAgICBjb2wudmFyID0gImJsYWNrIiwNCiAgICAgICAgICAgICAgICBnZW9tLnZhciA9IGMoInBvaW50IiwgInRleHQiKSwNCiAgICAgICAgICAgICAgICBmaWxsLmluZCA9IHBjYV9kYWRvcyRjbHVzdGVyLA0KICAgICAgICAgICAgICAgIGNvbC5pbmQgPSAiYmxhY2siLA0KICAgICAgICAgICAgICAgIHBvaW50c2hhcGUgPSAyMSwNCiAgICAgICAgICAgICAgICBwYWxldHRlID0gYygiIzY1QURDMiIsICIjMjMzQjQzIiwgIiNFODQ2NDYiKSwNCiAgICAgICAgICAgICAgICBsYWJlbCA9ICJ2YXIiLA0KICAgICAgICAgICAgICAgIHNlbGVjdC52YXI9IGxpc3QoY29zMiA9IDIwKSwgDQogICAgICAgICAgICAgICAgcG9pbnRzaXplID0gMywNCiAgICAgICAgICAgICAgICBhZGRFbGxpcHNlcyA9IFQsDQogICAgICAgICAgICAgICAgcmVwZWwgPSBUUlVFLA0KICAgICAgICAgICAgICAgIGxlZ2VuZC50aXRsZSA9ICJDbHVzdGVyIikgDQoNCnBjYV9wbG90X2tubl9jbHVzdGVyX2JpcGxvdA0KDQpwY2FfcGxvdF9rbm5fY2x1c3Rlcl9iaXBsb3QgJT4lIGdnc2F2ZShmaWxlID0gaGVyZSgiRmlndXJhcyIsIHBhc3RlMCgiUENBXyIsIG5pdmVsX3NlbGVjICwiXyIsIGFub19zZWxlYywiX0JpcGxvdC5wbmciKSksIHdpZHRoID0gMTAsIGhlaWdodCA9IDYpDQpgYGANCg0KDQojIyBNaWNyb3JyZWdpw6NvOiBEaXNwZXJzw6NvDQpgYGB7ciBmaWcud2lkdGggPSAxNSwgZmlnLmhlaWdodCA9IDEwfQ0KcG9wX3JlZ2lhbyA9IElFUFNfQ29tcGxldG9fMjAxMF8yMDIyX3NlbGVjaW9uYWRvc19TUCAlPiUNCiAgZmlsdGVyKG5pdmVsID09IG5pdmVsX3NlbGVjKSAlPiUgDQogICAgbXV0YXRlKHBvcnRlX3JlZ2lhbyA9IGNhc2Vfd2hlbihwb3AgPD0gMjAwMDAgfiAiUGVxdWVubyBQb3J0ZSBJIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3AgPD0gNTAwMDAgfiAiUGVxdWVubyBQb3J0ZSBJSSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9wIDw9IDEwMDAwMCB+ICJNw6lkaW8gUG9ydGUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcCA8PSA5MDAwMDAgfiAiR3JhbmRlIFBvcnRlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIH4gIk1ldHLDs3BvbGUiKSkgJT4lIA0KICBzZWxlY3Qocm93X25hbWVzLCBwb3J0ZV9tdW5pY2lwaW8pDQoNCg0KZGFkb3NfdmFjaW5hcyA9IElFUFNfQ29tcGxldG9fMjAxMF8yMDIyX3NlbGVjaW9uYWRvc19TUCAlPiUgDQogIGZpbHRlcihuaXZlbCA9PSBuaXZlbF9zZWxlYykgJT4lDQogIHNlbGVjdChyb3dfbmFtZXMsIGFubywgY29iX2FiOmNvYl92YWNfcGVudGEsIA0KICAgICAgICAgdHhfbW9ydF9hal9jZW5zOnBjdF9kZXNwX3JlY3Bfc2F1ZGVfbXVuLCANCiAgICAgICAgIGRlc3BfdG90X3NhdWRlX3BjX211bl9kZWYsDQogICAgICAgICBkZXNwX3JlY3Bfc2F1ZGVfcGNfbXVuX2RlZiwgDQogICAgICAgICBpZGViXzVhbm86cG9wLCANCiAgICAgICAgIHBjdF9wb3BfZmVtOnBjdF9wb3BfbWFzYykgJT4lIA0KICBpbm5lcl9qb2luKHBvcF9yZWdpYW8sIGJ5ID0gcm93X25hbWVzKSAlPiUgDQogIGRpc3RpbmN0KCkNCmBgYA0KDQoNCkNvcnJlbGHDp8OjbyBpZGViIGUgdmFjaW5hDQpgYGB7ciBmaWcud2lkdGggPSAyMCwgZmlnLmhlaWdodCA9IDEwfQ0KIyBsaWJyYXJ5KGVzcXVpc3NlKQ0KIyBsaWJyYXJ5KGdncG1pc2MpDQpjb3JfdmFjX2lkZWIgPSBkYWRvc192YWNpbmFzICU+JSANCiAgZmlsdGVyKCFhbm8gPT0geW1kKCIyMDIyLTAxLTAxIikpICU+JSANCiAgc2VsZWN0KGMocm93X25hbWVzLCAiaWRlYl81YW5vIiwgImlkZWJfOWFubyIsICJjb2JfdmFjX2JjZyIsICJhbm8iLCAicG9ydGVfbXVuaWNpcGlvIiwgInBvcCIpKSAlPiUgDQogIGdncGxvdCguKSArDQogIGFlcyh4ID0gaWRlYl81YW5vLCB5ID0gY29iX3ZhY19iY2cpICsNCiAgIyBnZW9tX3BvaW50KGNvbG9yID0gImJsYWNrIiwgDQogICMgICAgICAgICAgICBzaGFwZSA9ICJjaXJjbGUiKSArDQogIGdlb21fcG9pbnQoYWVzKGZpbGwgPSBwb3J0ZV9tdW5pY2lwaW8sIA0KICAgICAgICAgICAgICAgICBjb2xvdXIgPSBwb3J0ZV9tdW5pY2lwaW8sDQogICAgICAgICAgICAgICAgIHNpemUgPSBwb3ApLCANCiAgICAgICAgICAgICBzaGFwZSA9ICJjaXJjbGUiKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsDQogICAgICAgICAgICAgIGFscGhhID0gMC4xLA0KICAgICAgICAgICAgICBzZSA9IFQpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGV4cGFuc2lvbihhZGQgPSAyMCkpICsNCiAgICAgIHNjYWxlX3NpemVfY29udGludW91cyhyYW5nZSA9IGMoMiw4KSkgKw0KICBzdGF0X2NvcnJlbGF0aW9uKG1ldGhvZCA9ICJwZWFyc29uIiwNCiAgICAgICAgICAgICAgICAgICBzaXplID0gMy41LA0KICAgICAgICAgICAgICAgICAgIGxhYmVsLnggPSA1LCANCiAgICAgICAgICAgICAgICAgICBsYWJlbC55ID0gMTIwLA0KICAgICAgICAgICAgICAgICAgIG1hcHBpbmcgPSB1c2VfbGFiZWwoYygiUiIsICJSMiIsICJQIiwgIm4iKSkpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwNCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMSwxLDEsMSksICJjbSIpLA0KICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBmYWNlID0gInBsYWluIikpICArDQogIGxhYnModGl0bGUgPSAiQ29iZXJ0dXJhIHZhY2luYWwgZGEgQkNHIGUgSURFQiA1byBhbm8sIG1pY3JvcnJlZ2nDtWVzIGRvIGVzdGFkbyBkZSBTw6NvIFBhdWxvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJQZXLDrW9kbyBkZSAyMDEwIGEgMjAyMiIsDQogICAgICAgY2FwdGlvbiA9ICJGb250ZTogSUVQUywgUE5JLCBUYWJOZXQvREFUQVNVUyIsDQogICAgICAgY29sb3IgPSAiTWljcm9ycmVnacOjbyIsDQogICAgICAgeSA9ICJDb2JlcnR1cmEgdmFjaW5hbCAoJSkiLA0KICAgICAgIHggPSAiSURFQiIpICsNCiAgZmFjZXRfd3JhcCh+YW5vLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3cgPSAyKQ0KDQpjb3JfdmFjX2lkZWINCg0KY29yX3ZhY19pZGViICU+JSANCiAgZ2dzYXZlKGZpbGUgPSBoZXJlKCJGaWd1cmFzIiwgaGVyZSgiRmlndXJhcyIsIHBhc3RlMCgiUENBXyIsIG5pdmVsX3NlbGVjICwiXyIsIGFub19zZWxlYywiXzIwMTBfMjAyMF9CQ0dfdnNfSURFQi5wbmciKSkgDQogICAgICAgICB3aWR0aCA9IDIwLA0KICAgICAgICAgaGVpZ2h0ID0gMTApDQoNCmBgYA0KDQpJREhNIGUgdmFjaW5hDQoNCmBgYHtyIGZpZy53aWR0aCA9IDIwLCBmaWcuaGVpZ2h0ID0gMTB9DQpjb3JfdmFjX2lkaG0gPSBkYWRvc192YWNpbmFzICU+JSANCiAgZmlsdGVyKCFhbm8gPT0geW1kKCIyMDIyLTAxLTAxIikpICU+JSANCiAgc2VsZWN0KGMoIm5vX3JlZ2lhbyIsICJpZGhtIiwgImNvYl92YWNfYmNnIiwgImFubyIsICJwb3J0ZV9tdW5pY2lwaW8iLCAicG9wIikpICU+JSANCiAgZ2dwbG90KC4pICsNCiAgYWVzKHggPSBpZGhtLCB5ID0gY29iX3ZhY19iY2cpICsNCiAgIyBnZW9tX3BvaW50KGNvbG9yID0gImJsYWNrIiwgDQogICMgICAgICAgICAgICBzaGFwZSA9ICJjaXJjbGUiKSArDQogIGdlb21fcG9pbnQoYWVzKGZpbGwgPSBwb3J0ZV9tdW5pY2lwaW8sIA0KICAgICAgICAgICAgICAgICBjb2xvdXIgPSBwb3J0ZV9tdW5pY2lwaW8sDQogICAgICAgICAgICAgICAgIHNpemUgPSBwb3ApLCANCiAgICAgICAgICAgICBzaGFwZSA9ICJjaXJjbGUiKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsDQogICAgICAgICAgICAgIGFscGhhID0gMC4xLA0KICAgICAgICAgICAgICBzZSA9IFQpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGV4cGFuc2lvbihhZGQgPSAyMCkpICsNCiAgICAgIHNjYWxlX3NpemVfY29udGludW91cyhyYW5nZSA9IGMoMiw4KSkgKw0KICBzdGF0X2NvcnJlbGF0aW9uKG1ldGhvZCA9ICJwZWFyc29uIiwNCiAgICAgICAgICAgICAgICAgICBzaXplID0gMy41LA0KICAgICAgICAgICAgICAgICAgIGxhYmVsLnggPSA1LCANCiAgICAgICAgICAgICAgICAgICBsYWJlbC55ID0gMTIwLA0KICAgICAgICAgICAgICAgICAgIG1hcHBpbmcgPSB1c2VfbGFiZWwoYygiUiIsICJSMiIsICJQIiwgIm4iKSkpICsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwNCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDI1KSwNCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjApLA0KICAgICAgICBwbG90LmNhcHRpb24gPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICAgICAgcGxvdC5tYXJnaW4gPSB1bml0KGMoMSwxLDEsMSksICJjbSIpLA0KICAgICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBmYWNlID0gInBsYWluIikpICArDQogIGxhYnModGl0bGUgPSAiQ29iZXJ0dXJhIHZhY2luYWwgZGEgQkNHIGUgSURIIG11bmljaXBhbCwgbWljcm9ycmVnacO1ZXMgZG8gZXN0YWRvIGRlIFPDo28gUGF1bG8iLA0KICAgICAgIHN1YnRpdGxlID0gIlBlcsOtb2RvIGRlIDIwMTAgYSAyMDIyIiwNCiAgICAgICBjYXB0aW9uID0gIkZvbnRlOiBJRVBTLCBQTkksIFRhYk5ldC9EQVRBU1VTIiwNCiAgICAgICBjb2xvciA9ICJNaWNyb3JyZWdpw6NvIiwNCiAgICAgICB5ID0gIkNvYmVydHVyYSB2YWNpbmFsICglKSIsDQogICAgICAgeCA9ICJJREhNIikgKw0KICBmYWNldF93cmFwKH5hbm8sIHNjYWxlcyA9ICJmcmVlIiwgbnJvdyA9IDIpDQoNCmNvcl92YWNfaWRobQ0KDQpjb3JfdmFjX2lkaG0gJT4lIA0KICBnZ3NhdmUoZmlsZSA9IGhlcmUoIkZpZ3VyYXMiLCAiTWljcm9ycmVnaW9lc18yMDEwXzIwMjBfQkNHX3ZzX0lESE0ucG5nIiksIA0KICAgICAgICAgd2lkdGggPSAyMCwgaGVpZ2h0ID0gMTApDQpgYGANCg0KVGF4YSBkZSBtb3J0ZXMgZXZpdGF2ZWlzIGUgdmFjaW5hDQoNCmBgYHtyIGZpZy53aWR0aCA9IDIwLCBmaWcuaGVpZ2h0ID0gMTB9DQoNCnZhcmlhdmVsX2ludGVyZXNzZSA9ICJ0eF9tb3J0X2V2aXRfYWpfY2VucyINCg0KY29yX3ZhY190eG1vcnRlcyA9IGRhZG9zX3ZhY2luYXMgJT4lIA0KICBmaWx0ZXIoIWFubyA9PSB5bWQoIjIwMjItMDEtMDEiKSkgJT4lIA0KICBzZWxlY3QoYygibm9fcmVnaWFvIiwgdmFyaWF2ZWxfaW50ZXJlc3NlLCAiY29iX3ZhY19iY2ciLCAiYW5vIiwgInBvcnRlX211bmljaXBpbyIsICJwb3AiKSkgJT4lIA0KICBnZ3Bsb3QoLikgKw0KICBhZXMoeCA9IHZhcmlhdmVsX2ludGVyZXNzZSwgeSA9IGNvYl92YWNfYmNnKSArDQogICMgZ2VvbV9wb2ludChjb2xvciA9ICJibGFjayIsIA0KICAjICAgICAgICAgICAgc2hhcGUgPSAiY2lyY2xlIikgKw0KICBnZW9tX3BvaW50KGFlcyhmaWxsID0gcG9ydGVfbXVuaWNpcGlvLCANCiAgICAgICAgICAgICAgICAgY29sb3VyID0gcG9ydGVfbXVuaWNpcGlvLA0KICAgICAgICAgICAgICAgICBzaXplID0gcG9wKSwgDQogICAgICAgICAgICAgc2hhcGUgPSAiY2lyY2xlIikgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLA0KICAgICAgICAgICAgICBhbHBoYSA9IDAuMSwNCiAgICAgICAgICAgICAgc2UgPSBUKSArDQogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBleHBhbnNpb24oYWRkID0gMjApKSArDQogICAgICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDIsOCkpICsNCiAgc3RhdF9jb3JyZWxhdGlvbihtZXRob2QgPSAicGVhcnNvbiIsDQogICAgICAgICAgICAgICAgICAgc2l6ZSA9IDMuNSwNCiAgICAgICAgICAgICAgICAgICBsYWJlbC54ID0gNSwgDQogICAgICAgICAgICAgICAgICAgbGFiZWwueSA9IDEyMCwNCiAgICAgICAgICAgICAgICAgICBtYXBwaW5nID0gdXNlX2xhYmVsKGMoIlIiLCAiUjIiLCAiUCIsICJuIikpKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksDQogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgICAgIHBsb3QubWFyZ2luID0gdW5pdChjKDEsMSwxLDEpLCAiY20iKSwNCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgZmFjZSA9ICJwbGFpbiIpKSAgKw0KICBsYWJzKHRpdGxlID0gIkNvYmVydHVyYSB2YWNpbmFsIGRhIEJDRyBlIFRheGEgZGUgbW9ydGVzIGV2aXRhdmVpcyAoQ0VOU08pLCBtaWNyb3JyZWdpw7VlcyBkbyBlc3RhZG8gZGUgU8OjbyBQYXVsbyIsDQogICAgICAgc3VidGl0bGUgPSAiUGVyw61vZG8gZGUgMjAxMCBhIDIwMjIiLA0KICAgICAgIGNhcHRpb24gPSAiRm9udGU6IElFUFMsIFBOSSwgVGFiTmV0L0RBVEFTVVMiLA0KICAgICAgIGNvbG9yID0gIk1pY3JvcnJlZ2nDo28iLA0KICAgICAgIHkgPSAiVGF4YSBkZSBtb3J0ZXMgZXZpdGF2ZWlzIChDRU5TTykiLA0KICAgICAgIHggPSAiSURITSIpICsNCiAgZmFjZXRfd3JhcCh+YW5vLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3cgPSAyKQ0KDQpjb3JfdmFjX3R4bW9ydGVzDQoNCmNvcl92YWNfdHhtb3J0ZXMgJT4lIA0KICBnZ3NhdmUoZmlsZSA9IGhlcmUoIkZpZ3VyYXMiLCAiTWljcm9ycmVnaW9lc18yMDEwXzIwMjBfQkNHX3ZzX1RheGFfTW9ydGVzX0V2aXRhdmVpcy5wbmciKSwgDQogICAgICAgICB3aWR0aCA9IDIwLCBoZWlnaHQgPSAxMCkNCmBgYA0KDQojIE11bmljw61waW8NCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZ2dyZXBlbCkgI2xvYWQgYmVmb3JlIGZhY3RvZXh0cmENCmxpYnJhcnkoZmFjdG9leHRyYSkNCmxpYnJhcnkoY2FyZXQpDQpsaWJyYXJ5KHN0YXRzKQ0KbGlicmFyeShnZ2ZvcnRpZnkpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KGNvcnJwbG90KQ0KbGlicmFyeShjb3dwbG90KQ0KbGlicmFyeShnZ2NvcnJwbG90KQ0KbGlicmFyeShDb21wbGV4SGVhdG1hcCkNCmxpYnJhcnkoY2lyY2xpemUpDQpsaWJyYXJ5KGdnRXh0cmEpDQpsaWJyYXJ5KEZhY3RvTWluZVIpDQpgYGANCg0KDQoNCg0KIyMgTXVuY8OtcGlvczogU2VsZWNpb25hZG9zDQoNCmBgYHtyfQ0KDQphbm9fc2VsZWMgPSAiMjAyMC0wMS0wMSINCm5pdmVsX3NlbGVjID0gIk11bmljw61waW8iDQpyb3dfbmFtZXMgPSAibm9tZW11biINCg0KcGNhX211bmljaXBpbyA9IElFUFNfQ29tcGxldG9fMjAxMF8yMDIyX3NlbGVjaW9uYWRvc19TUCAlPiUgDQogIGZpbHRlcihuaXZlbCA9PSAiTXVuaWPDrXBpbyIsDQogICAgICAgICBhbm8gPT0geW1kKGFub19zZWxlYykpICU+JQ0KICBjb2x1bW5fdG9fcm93bmFtZXMoIm5vbWVtdW4iKSAlPiUgDQogIHNlbGVjdChjb2JfYWI6Y29iX3ZhY19wZW50YSwgDQogICAgICAgICB0eF9tb3J0X2FqX2NlbnM6cGN0X2Rlc3BfcmVjcF9zYXVkZV9tdW4sIA0KICAgICAgICAgZGVzcF90b3Rfc2F1ZGVfcGNfbXVuX2RlZiwNCiAgICAgICAgIGRlc3BfcmVjcF9zYXVkZV9wY19tdW5fZGVmLCANCiAgICAgICAgIGlkZWJfNWFubzpwb3AsIA0KICAgICAgICAgcGN0X3BvcF9mZW06cGN0X3BvcF9tYXNjKQ0KDQpwY2FfbXVuaWNpcGlvX21hdHJpeCA9IHBjYV9tdW5pY2lwaW8gJT4lIA0KICBhcy5tYXRyaXgoKQ0KDQpkaW0ocGNhX211bmljaXBpb19tYXRyaXgpDQoNCnBjYV9tdW5pY2lwaW9fYW5uID0gSUVQU19Db21wbGV0b18yMDEwXzIwMjJfc2VsZWNpb25hZG9zX1NQICU+JSANCiAgZmlsdGVyKG5pdmVsID09ICJNdW5pY8OtcGlvIiwNCiAgICAgICAgIGFubyA9PSB5bWQoYW5vX3NlbGVjKSkgJT4lIA0KICBzZWxlY3Qobm9tZW11biwgcG9wKSAlPiUgDQogIG11dGF0ZShwb3J0ZV9tdW5pY2lwaW8gPSBjYXNlX3doZW4ocG9wIDw9IDIwMDAwIH4gIlBlcXVlbm8gUG9ydGUgSSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9wIDw9IDUwMDAwIH4gIlBlcXVlbm8gUG9ydGUgSUkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcCA8PSAxMDAwMDAgfiAiTcOpZGlvIFBvcnRlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3AgPD0gOTAwMDAwIH4gIkdyYW5kZSBQb3J0ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+ICJNZXRyw7Nwb2xlIiksDQogICAgICAgICBJRCA9IG5vbWVtdW4pICU+JSANCiAgc2VsZWN0KC1wb3ApICU+JSANCiAgICBjb2x1bW5fdG9fcm93bmFtZXMoIm5vbWVtdW4iKQ0KYGBgDQoNCg0KYGBge3J9DQpwY2FfbXVuaWNpcGlvICU+JSANCiAgZ2dwbG90KCkNCmBgYA0KDQoNCg0KDQpgYGB7ciBmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDEwfQ0KIyBEZWxldGUgY29sdW1ucyB3aXRoIG5lYXIgMCB2YXJpYW5jZQ0KbmVhclplcm9WYXJDb2xzIDwtIG5lYXJaZXJvVmFyKHBjYV9tdW5pY2lwaW9fbWF0cml4LCBzYXZlTWV0cmljcyA9IFRSVUUpDQpwY2FfbXVuaWNpcGlvX21hdHJpeF9wY2EgPC0gcGNhX211bmljaXBpb19tYXRyaXhbLCAhbmVhclplcm9WYXJDb2xzJG56dl0NCnBjYV9yZXMgPC0gcHJjb21wKHBjYV9tdW5pY2lwaW9fbWF0cml4X3BjYSwgc2NhbGUuID0gVCkNCg0KIyBDb3JyZWxhdGlvbiBwbG90IC0tLS0NCmNvcnJfbWF0cml4ID0gY29yKHBjYV9tdW5pY2lwaW9fbWF0cml4X3BjYSAlPiUgc2NhbGUoKSkgDQp2YXIgPC0gZ2V0X3BjYV92YXIocGNhX3JlcykNCg0KY29ycl9tYXRyaXhfc2VsZWMgPSBjb3JyX21hdHJpeCAlPiUgDQogIGFzLmRhdGEuZnJhbWUoKSAlPiUgDQogIHJvd25hbWVzX3RvX2NvbHVtbigiaWQiKSAlPiUgDQogIGZpbHRlcihzdHJfZGV0ZWN0KGlkLCAiY29iX3ZhYyIpKSAlPiUgDQogIGNvbHVtbl90b19yb3duYW1lcygiaWQiKSAlPiUgDQogIGFzLm1hdHJpeCgpDQoNCg0KcC5tYXQgPSBjb3JfcG1hdChwY2FfbXVuaWNpcGlvX21hdHJpeF9wY2EgJT4lIHNjYWxlKCkpDQoNCnAubWF0XzIgPSBjb3JfcG1hdChjb3JyX21hdHJpeF9zZWxlYyAlPiUgc2NhbGUoKSkgJT4lIA0KICBhcy5kYXRhLmZyYW1lKCkgJT4lIA0KICByb3duYW1lc190b19jb2x1bW4oImlkIikgJT4lIA0KICBpbm5lcl9qb2luKGNvcnJfbWF0cml4X3NlbGVjICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigiaWQiKSAlPiUgc2VsZWN0KCJpZCIpLCBieSA9ICJpZCIpICU+JSANCiAgY29sdW1uX3RvX3Jvd25hbWVzKCJpZCIpICU+JSANCiAgYXMubWF0cml4KCkNCg0KDQoNCiNTZWxlY2lvbmFkb3MNCnBuZyhmaWxlID0gaGVyZSgiRmlndXJhcyIsIHBhc3RlMCgiUENBXyIsIG5pdmVsX3NlbGVjICwiXyIsIGFub19zZWxlYywgIl9TZWxlY2lvbmFkb3NfQ29ycnBsb3QucG5nIikpLCANCiAgICB3aWR0aCA9IDE1LCBoZWlnaHQgPSA1LA0KICAgIHVuaXRzID0gImluIiwNCiAgICByZXMgPSAzMDApDQoNCmNvcnJwbG90KHJvdW5kKGNvcnJfbWF0cml4X3NlbGVjLCAyKSwNCiAgICAgICAgIGlzLmNvcnIgPSBUUlVFLA0KICAgICAgICAgdGwuY29sID0gImJsYWNrIiwNCiAgICAgICAgIHRpdGxlID0gIkNvYmVydHVyYSB2YWNpbmFsIGUgaW5kaWNhZG9yZXMgc29jaWFpcywgZWNvbm9taWNvcywgZGVtb2dyw6FmaWNvcyBlIGRlIHNhw7pkZSIsDQogICAgICAgICBjZXgubWFpbiA9IDIsDQogICAgICAgICBtZXRob2QgPSAiY29sb3IiLA0KICAgICAgICAgcC5tYXQgPSBwLm1hdF8yLA0KICAgICAgICAgdGwuc3J0ID0gNDUsDQogICAgICAgICBzaWcubGV2ZWwgPSBjKDAuMDUpLA0KICAgICAgICAgbWFyPWMoMSwwLDQsMCksDQogICAgICAgICBhZGRDb2VmLmNvbCA9ICdibGFjaycsDQogICAgICAgICBudW1iZXIuY2V4ID0gMC42LA0KICAgICAgICAgaW5zaWcgPSAiYmxhbmsiLA0KICAgICAgICAgY29sID0gY29sb3JSYW1wUGFsZXR0ZShjKCIjNjVBREMyIiwgIndoaXRlIiwgIiNFODQ2NDYiKSkoMTEpKQ0KDQpkZXYub2ZmKCkNCmBgYA0KDQoNCmBgYHtyIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gMTB9DQojVG9kb3Mgb3MgaW5kaWNhZG9yZXMNCg0KY29ycnBsb3QgPSBnZ2NvcnJwbG90KGNvcnJfbWF0cml4LCBoYy5vcmRlciA9IFRSVUUsDQogICAgICAgICAgIG1ldGhvZCA9ICJjaXJjbGUiLA0KICAgICAgICAgICB0eXBlID0gImZ1bGwiLA0KICAgICAgICAgICBnZ3RoZW1lID0gTlVMTCwNCiAgICAgICAgICAgb3V0bGluZS5jb2wgPSAid2hpdGUiLCANCiAgICAgICAgICAgcC5tYXQgPSBwLm1hdCwNCiAgICAgICAgICAgc2lnLmxldmVsID0gMC4wNSwgDQogICAgICAgICAgIGNvbG9ycyA9IGMoIiM2NUFEQzIiLCAid2hpdGUiLCAiI0U4NDY0NiIpKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIHNpemUgPSAxMCksDQogICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCkpICsNCiAgbGFicyh0aXRsZSA9ICJDb2JlcnR1cmEgdmFjaW5hbCBlIGluZGljYWRvcmVzIHNvY2lhaXMsIGVjb25vbWljb3MsIGRlbW9ncsOhZmljb3MgZSBkZSBzYcO6ZGUiKSArDQogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBmYWNlID0gImJvbGQiKSkNCg0KY29ycnBsb3QNCg0KY29ycnBsb3QgJT4lIA0KICBnZ3NhdmUoZmlsZSA9IGhlcmUoIkZpZ3VyYXMiLCAiUENBX011bmljw61waW9zXzIwMjBfQ29ycnBsb3QucG5nIiksIHdpZHRoID0gMTIsIGhlaWdodCA9IDEwKQ0KDQpgYGANCg0KDQpgYGB7ciBmaWcud2lkdGggPSA1LCBmaWcuaGVpZ2h0ID0gNX0NCiNQQ0EgLS0tLQ0KZGF0YS5wY2EgPSBwcmNvbXAoY29ycl9tYXRyaXgpICNQQ0ENCnN1bW1hcnkoY29ycl9tYXRyaXgpICNSZXRvcm5hciBQQ3MNCg0KI1NjcmVlIHBsb3QgLS0tLQ0Kc2NyZWVfcGxvdCA9IGZ2aXpfZWlnKGRhdGEucGNhLCANCiAgICAgICAgICAgICAgICAgICAgICBhZGRsYWJlbHMgPSBUUlVFLA0KICAgICAgICAgICAgICAgICAgICAgIHlsaW0gPSBjKDAsIDcwKSkgKw0KICBnZW9tX2NvbChjb2xvciA9ICIjMDBBRkJCIiwgZmlsbCA9ICIjMDBBRkJCIikgDQoNCnNjcmVlX3Bsb3QNCg0Kc2NyZWVfcGxvdCAlPiUgDQogIGdnc2F2ZShmaWxlID0gaGVyZSgiRmlndXJhcyIsICJQQ0FfTXVuaWPDrXBpb3NfMjAyMF9TZWxlY2lvbmFkb3NfU2NyZWVwbG90LnBuZyIpLCANCiAgICAgICAgIHdpZHRoID0gNSwNCiAgICAgICAgIGhlaWdodCA9IDMpDQpgYGANCg0KDQpgYGB7ciBmaWcud2lkdGggPSA3LCBmaWcuaGVpZ2h0ID0gN30NCiMgTG9hZGluZ3MgcGxvdCAtLS0tDQpvcHRpb25zKGdncmVwZWwubWF4Lm92ZXJsYXBzID0gSW5mKQ0KDQpjaXJjbGVfY29udHJpYj0gZnZpel9wY2FfdmFyKHBjYV9yZXMsIGNvbC52YXIgPSAiY29zMiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncmFkaWVudC5jb2xzID0gYygiIzY1QURDMiIsICJibGFjayIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0LnZhcj0gbGlzdChjb3MyID0gMzApLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGVsID0gVCwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHNpemUgPSA0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sLmNpcmNsZSA9IE5BKSANCg0KY2lyY2xlX2NvbnRyaWINCg0KY2lyY2xlX2NvbnRyaWIgJT4lIA0KICBnZ3NhdmUoZmlsZSA9IGhlcmUoIkZpZ3VyYXMiLCAiUENBX011bmljw61waW9zXzIwMjBfU2VsZWNpb25hZG9zX0xvYWRpbmdzLnBuZyIpLCANCiAgICAgICAgIHdpZHRoID0gNSwgDQogICAgICAgICBoZWlnaHQgPSA1KQ0KDQpgYGANCg0KYGBge3IgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA2fQ0KIyBDbHVzdGVyIC0tLS0tLQ0KI0RldGVybWluZSB0aGUgbnVtYmVyIG9mIGNsdXN0ZXJzDQpwY2Ffc2NvcmVzIDwtIGRhdGEuZnJhbWUocGNhX3JlcyR4WywgMToyXSkNCmZ2aXpfbmJjbHVzdChwY2Ffc2NvcmVzLCAgDQogICAgICAgICAgICAgICAgICAgICBGVU5jbHVzdGVyID0ga21lYW5zLA0KICAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gIndzcyIpDQoNCg0Kc2V0LnNlZWQoNjY2KSAjIFNldCBzZWVkIGZvciByYW5kb21pemF0aW9uDQpjbHVzdGVyX21vZGVsIDwtIGttZWFucyhwY2FfcmVzJHhbLCAxOjJdLCBjZW50ZXJzID0gMykgICNTZXQgdGhlIG51bWJlciBvZiBjbHVzdGVycw0KDQpwY2FfbXVuaWNpcGlvJGNsdXN0ZXIgPC0gYXMuZmFjdG9yKGNsdXN0ZXJfbW9kZWwkY2x1c3RlcikNCnBjYV9tdW5pY2lwaW8gPSBwY2FfbXVuaWNpcGlvICU+JSANCiAgcm93bmFtZXNfdG9fY29sdW1uKCJpZCIpDQpgYGANCg0KDQpgYGB7ciBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDZ9DQojIFBsb3QgLS0tLS0tDQpwY2FfcGxvdF9rbm5fY2x1c3RlciA9IGF1dG9wbG90KHBjYV9yZXMsIA0KICAgICAgICBkYXRhID0gcGNhX211bmljaXBpbywgDQogICAgICAgIGNvbG91ciA9ICdjbHVzdGVyJykgICsNCiAgc3RhdF9lbGxpcHNlKGFlcyhjb2xvciA9IGNsdXN0ZXIsIA0KICAgICAgICAgICAgICAgICAgIGZpbGwgPSBjbHVzdGVyKSwgDQogICAgICAgICAgICAgICBnZW9tID0gInBvbHlnb24iLCANCiAgICAgICAgICAgICAgIGFscGhhID0gMC4xLCANCiAgICAgICAgICAgICAgIGxpbmV0eXBlID0gMSwNCiAgICAgICAgICAgICAgIHNpemUgPSAwLjMsDQogICAgICAgICAgICAgICB0eXBlID0gInQiKSArDQogIGdlb21fcG9pbnQoYWVzKGZpbGwgPSBjbHVzdGVyLA0KICAgICAgICAgICAgICAgICBzaXplID0gcG9wKSwNCiAgICAgICAgICAgICBjb2xvdXI9ImJsYWNrIiwNCiAgICAgICAgICAgICBwY2g9MjEpICsNCiAgbGFicyh0aXRsZSA9ICJNdW5pY8OtcGlvcyBwYXVsaXN0YXMsIDIwMjAiKSArIA0KICB0aGVtZSh0ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG9yID0gImJsYWNrIikpICsNCiAgIyBnZW9tX2xhYmVsX3JlcGVsKGFlcyhsYWJlbCA9IGlkLA0KICAjICAgICAgICAgICAgICAgICAgICAgc2VnbWVudC5jb2xvdXI9ICJibGFjayIpLA0KICAjICAgICAgICAgICAgICAgICBib3gucGFkZGluZyA9IDAuMywNCiAgIyAgICAgICAgICAgICAgICAgc2l6ZSA9IDMpICArDQogIHNjYWxlX3NpemVfY29udGludW91cyhyYW5nZSA9IGMoMSw4KSkNCnBjYV9wbG90X2tubl9jbHVzdGVyX21hcmdpbmFsID0gZ2dNYXJnaW5hbCgNCiAgcGNhX3Bsb3Rfa25uX2NsdXN0ZXIsDQogIGdyb3VwRmlsbCA9IFQsDQogIGdyb3VwQ29sb3VyID0gVCkNCnBjYV9wbG90X2tubl9jbHVzdGVyX21hcmdpbmFsDQoNCnBjYV9wbG90X2tubl9jbHVzdGVyX21hcmdpbmFsICU+JSBnZ3NhdmUoZmlsZSA9IGhlcmUoIkZpZ3VyYXMiLCAiUENBX011bmljw61waW9zXzIwMjBfU2VsZWNpb25hZG9zX0NsdXN0ZXJzLnBuZyIpLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2KQ0KDQpgYGANCg0KYGBge3IgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA2fQ0KZ2d0aGVtcigiZnJlc2giLCBzcGFjaW5nID0gMSkNCnN3YXRjaCgpDQoNCnBjYV9wbG90X2tubl9jbHVzdGVyX2dyYWRpZW50ID0gYXV0b3Bsb3QocGNhX3JlcywgDQogICAgICAgIGRhdGEgPSBwY2FfbXVuaWNpcGlvKSAgKw0KICBnZW9tX3BvaW50KGFlcyhmaWxsID0gY29iX3ZhY19wb2xpbywNCiAgICAgICAgICAgICAgICAgc2l6ZSA9IHBvcCksDQogICAgICAgICAgICAgY29sb3VyPSJibGFjayIsDQogICAgICAgICAgICAgcGNoPTIxKSArDQogIGxhYnModGl0bGUgPSAiTWljcm9ycmVnacO1ZXMgcGF1bGlzdGFzLCAyMDIwIikgKyANCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKSAgKw0KICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICIjRTg0NjQ2IiwgaGlnaCA9ICIjNjVBREMyIikgKw0KICAgIHNjYWxlX3NpemVfY29udGludW91cyhyYW5nZSA9IGMoNCw4KSkNCg0KDQpwY2FfcGxvdF9rbm5fY2x1c3Rlcl9ncmFkaWVudA0KDQpwY2FfcGxvdF9rbm5fY2x1c3Rlcl9ncmFkaWVudCAlPiUgZ2dzYXZlKGZpbGUgPSBoZXJlKCJGaWd1cmFzIiwgIlBDQV9NdW5pY2lwaW9zXzIwMjBfU2VsZWNpb25hZG9zX1BvbGlvLnBuZyIpLCB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2KQ0KYGBgDQoNCmBgYHtyIGZpZy53aWR0aCA9IDEwLCBmaWcuaGVpZ2h0ID0gNn0NCmdndGhlbXIoImZyZXNoIiwgc3BhY2luZyA9IDEpDQpzd2F0Y2goKQ0KDQpwY2FfbXVuaWNpcGlvXzIgPSBwY2FfbXVuaWNpcGlvICU+JSANCiAgYmluZF9jb2xzKHBjYV9tdW5pY2lwaW9fYW5uKQ0KcGNhX3Bsb3Rfa25uX2NsdXN0ZXJfZ3JhZGllbnQgPSBhdXRvcGxvdChwY2FfcmVzLCANCiAgICAgICAgZGF0YSA9IHBjYV9tdW5pY2lwaW9fMikgICsNCiAgZ2VvbV9wb2ludChhZXMoZmlsbCA9IHBvcnRlX211bmljaXBpbywNCiAgICAgICAgICAgICAgICAgc2l6ZSA9IHBvcCksDQogICAgICAgICAgICAgY29sb3VyPSJibGFjayIsDQogICAgICAgICAgICAgcGNoPTIxKSArDQogIGxhYnModGl0bGUgPSAiTWljcm9ycmVnacO1ZXMgcGF1bGlzdGFzLCAyMDIwIikgKyANCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKSAgKw0KICAgIHNjYWxlX3NpemVfY29udGludW91cyhyYW5nZSA9IGMoNCw4KSkNCg0KDQpwY2FfcGxvdF9rbm5fY2x1c3Rlcl9ncmFkaWVudA0KDQpwY2FfcGxvdF9rbm5fY2x1c3Rlcl9ncmFkaWVudCAlPiUgZ2dzYXZlKGZpbGUgPSBoZXJlKCJGaWd1cmFzIiwgIlBDQV9NdW5pY2lwaW9zXzIwMjBfU2VsZWNpb25hZG9zX1BvcnRlTXVuaWNwaW8ucG5nIiksIHdpZHRoID0gMTAsIGhlaWdodCA9IDYpDQpgYGANCg0KDQoNCg0KYGBge3IgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA2fQ0KIiMxMTExMTEiICIjNjVBREMyIiAiIzIzM0I0MyIgIiNFODQ2NDYiICIjQzI5MzY1IiAiIzM2MkMyMSIgIiMzMTY2NzUiICIjMTY4RTdGIiAiIzEwOUIzNyINCnJlcy5rbSA8LSBrbWVhbnModmFyJGNvb3JkLCBjZW50ZXJzID0gMywgbnN0YXJ0ID0gMjUpDQpncnAgPC0gYXMuZmFjdG9yKHJlcy5rbSRjbHVzdGVyKQ0KDQpwY2FfcGxvdF9rbm5fY2x1c3Rlcl9iaXBsb3QgPSBmdml6X3BjYV9iaXBsb3QocGNhX3JlcywgDQogICAgICAgICAgICAgICAgY29sLnZhciA9ICJibGFjayIsDQogICAgICAgICAgICAgICAgZ2VvbS52YXIgPSBjKCJwb2ludCIsICJ0ZXh0IiksDQogICAgICAgICAgICAgICAgZmlsbC5pbmQgPSBwY2FfbXVuaWNpcGlvJGNsdXN0ZXIsDQogICAgICAgICAgICAgICAgY29sLmluZCA9ICJibGFjayIsDQogICAgICAgICAgICAgICAgcG9pbnRzaGFwZSA9IDIxLA0KICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjNjVBREMyIiwgIiMyMzNCNDMiLCAiI0U4NDY0NiIpLA0KICAgICAgICAgICAgICAgIGxhYmVsID0gInZhciIsDQogICAgICAgICAgICAgICAgc2VsZWN0LnZhcj0gbGlzdChjb3MyID0gMjApLCANCiAgICAgICAgICAgICAgICBwb2ludHNpemUgPSAzLA0KICAgICAgICAgICAgICAgIGFkZEVsbGlwc2VzID0gVCwNCiAgICAgICAgICAgICAgICByZXBlbCA9IFRSVUUsDQogICAgICAgICAgICAgICAgbGVnZW5kLnRpdGxlID0gIkNsdXN0ZXIiKSANCg0KcGNhX3Bsb3Rfa25uX2NsdXN0ZXJfYmlwbG90DQoNCnBjYV9wbG90X2tubl9jbHVzdGVyX2JpcGxvdCAlPiUgZ2dzYXZlKGZpbGUgPSBoZXJlKCJGaWd1cmFzIiwgIlBDQV9NdW5pY2lwaW9zXzIwMjBfU2VsZWNpb25hZG9zX0JpcGxvdC5wbmciKSwgd2lkdGggPSAxMCwgaGVpZ2h0ID0gNikNCmBgYA0KDQoNCiMgQ29ycmVsYcOnw6NvOiBEaXNwZXJzw6NvDQpgYGB7ciBmaWcud2lkdGggPSAxNSwgZmlnLmhlaWdodCA9IDEwfQ0KcG9wX211bmljaXBpbyA9IElFUFNfQ29tcGxldG9fMjAxMF8yMDIyX3NlbGVjaW9uYWRvc19TUCAlPiUNCiAgZmlsdGVyKG5pdmVsID09ICJNdW5pY8OtcGlvIikgJT4lIA0KICAgIG11dGF0ZShwb3J0ZV9tdW5pY2lwaW8gPSBjYXNlX3doZW4ocG9wIDw9IDIwMDAwIH4gIlBlcXVlbm8gUG9ydGUgSSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9wIDw9IDUwMDAwIH4gIlBlcXVlbm8gUG9ydGUgSUkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvcCA8PSAxMDAwMDAgfiAiTcOpZGlvIFBvcnRlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3AgPD0gOTAwMDAwIH4gIkdyYW5kZSBQb3J0ZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSB+ICJNZXRyw7Nwb2xlIikpICU+JSANCiAgc2VsZWN0KG5vbWVtdW4sIHBvcnRlX211bmljaXBpbykNCg0KDQpkYWRvc192YWNpbmFzID0gSUVQU19Db21wbGV0b18yMDEwXzIwMjJfc2VsZWNpb25hZG9zX1NQICU+JSANCiAgZmlsdGVyKG5pdmVsID09ICJNdW5pY8OtcGlvIikgJT4lDQogIHNlbGVjdChub21lbXVuLCBhbm8sIGNvYl9hYjpjb2JfdmFjX3BlbnRhLCANCiAgICAgICAgIHR4X21vcnRfYWpfY2VuczpwY3RfZGVzcF9yZWNwX3NhdWRlX211biwgDQogICAgICAgICBkZXNwX3RvdF9zYXVkZV9wY19tdW5fZGVmLA0KICAgICAgICAgZGVzcF9yZWNwX3NhdWRlX3BjX211bl9kZWYsIA0KICAgICAgICAgaWRlYl81YW5vOnBvcCwgDQogICAgICAgICBwY3RfcG9wX2ZlbTpwY3RfcG9wX21hc2MpICU+JSANCiAgaW5uZXJfam9pbihwb3BfbXVuaWNpcGlvLCBieSA9ICJub21lbXVuIikgJT4lIA0KICBkaXN0aW5jdCgpDQpgYGANCg0KDQpDb3JyZWxhw6fDo28gaWRlYiBlIHZhY2luYQ0KYGBge3IgZmlnLndpZHRoID0gMjAsIGZpZy5oZWlnaHQgPSAxMH0NCiMgbGlicmFyeShlc3F1aXNzZSkNCiMgbGlicmFyeShnZ3BtaXNjKQ0KY29yX3ZhY19pZGViID0gZGFkb3NfdmFjaW5hcyAlPiUgDQogIGZpbHRlcighYW5vID09IHltZCgiMjAyMi0wMS0wMSIpKSAlPiUgDQogIHNlbGVjdChjKCJub21lbXVuIiwgImlkZWJfNWFubyIsICJpZGViXzlhbm8iLCAiY29iX3ZhY19iY2ciLCAiYW5vIiwgInBvcnRlX211bmljaXBpbyIsICJwb3AiKSkgJT4lIA0KICBnZ3Bsb3QoLikgKw0KICBhZXMoeCA9IGlkZWJfNWFubywgeSA9IGNvYl92YWNfYmNnKSArDQogICMgZ2VvbV9wb2ludChjb2xvciA9ICJibGFjayIsIA0KICAjICAgICAgICAgICAgc2hhcGUgPSAiY2lyY2xlIikgKw0KICBnZW9tX3BvaW50KGFlcyhmaWxsID0gcG9ydGVfbXVuaWNpcGlvLCANCiAgICAgICAgICAgICAgICAgY29sb3VyID0gcG9ydGVfbXVuaWNpcGlvLA0KICAgICAgICAgICAgICAgICBzaXplID0gcG9wKSwgDQogICAgICAgICAgICAgc2hhcGUgPSAiY2lyY2xlIikgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLA0KICAgICAgICAgICAgICBhbHBoYSA9IDAuMSwNCiAgICAgICAgICAgICAgc2UgPSBUKSArDQogIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBleHBhbnNpb24oYWRkID0gMjApKSArDQogICAgICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDIsOCkpICsNCiAgc3RhdF9jb3JyZWxhdGlvbihtZXRob2QgPSAicGVhcnNvbiIsDQogICAgICAgICAgICAgICAgICAgc2l6ZSA9IDMuNSwNCiAgICAgICAgICAgICAgICAgICBsYWJlbC54ID0gNSwgDQogICAgICAgICAgICAgICAgICAgbGFiZWwueSA9IDEyMCwNCiAgICAgICAgICAgICAgICAgICBtYXBwaW5nID0gdXNlX2xhYmVsKGMoIlIiLCAiUjIiLCAiUCIsICJuIikpKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksDQogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgICAgIHBsb3QubWFyZ2luID0gdW5pdChjKDEsMSwxLDEpLCAiY20iKSwNCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgZmFjZSA9ICJwbGFpbiIpKSAgKw0KICBsYWJzKHRpdGxlID0gIkNvYmVydHVyYSB2YWNpbmFsIGRhIEJDRyBlIElERUIgNW8gYW5vLCBtdW5pY8OtcGlvcyBkbyBlc3RhZG8gZGUgU8OjbyBQYXVsbyIsDQogICAgICAgc3VidGl0bGUgPSAiUGVyw61vZG8gZGUgMjAxMCBhIDIwMjIiLA0KICAgICAgIGNhcHRpb24gPSAiRm9udGU6IElFUFMsIFBOSSwgVGFiTmV0L0RBVEFTVVMiLA0KICAgICAgIGNvbG9yID0gIk11bmljaXBpbyIsDQogICAgICAgeSA9ICJDb2JlcnR1cmEgdmFjaW5hbCAoJSkiLA0KICAgICAgIHggPSAiSURFQiIpICsNCiAgZmFjZXRfd3JhcCh+YW5vLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3cgPSAyKQ0KDQpjb3JfdmFjX2lkZWINCg0KY29yX3ZhY19pZGViICU+JSANCiAgZ2dzYXZlKGZpbGUgPSBoZXJlKCJGaWd1cmFzIiwgIk11bmljaXBpb3NfMjAxMF8yMDIwX0JDR192c19JREVCLnBuZyIpLCANCiAgICAgICAgIHdpZHRoID0gMjAsDQogICAgICAgICBoZWlnaHQgPSAxMCkNCg0KYGBgDQoNCklESE0gZSB2YWNpbmENCg0KYGBge3IgZmlnLndpZHRoID0gMjAsIGZpZy5oZWlnaHQgPSAxMH0NCmNvcl92YWNfaWRobSA9IGRhZG9zX3ZhY2luYXMgJT4lIA0KICBmaWx0ZXIoIWFubyA9PSB5bWQoIjIwMjItMDEtMDEiKSkgJT4lIA0KICBzZWxlY3QoYygibm9tZW11biIsICJpZGhtIiwgImNvYl92YWNfYmNnIiwgImFubyIsICJwb3J0ZV9tdW5pY2lwaW8iLCAicG9wIikpICU+JSANCiAgZ2dwbG90KC4pICsNCiAgYWVzKHggPSBpZGhtLCB5ID0gY29iX3ZhY19iY2cpICsNCiAgIyBnZW9tX3BvaW50KGNvbG9yID0gImJsYWNrIiwgDQogICMgICAgICAgICAgICBzaGFwZSA9ICJjaXJjbGUiKSArDQogIGdlb21fcG9pbnQoYWVzKGZpbGwgPSBwb3J0ZV9tdW5pY2lwaW8sIA0KICAgICAgICAgICAgICAgICBjb2xvdXIgPSBwb3J0ZV9tdW5pY2lwaW8sDQogICAgICAgICAgICAgICAgIHNpemUgPSBwb3ApLCANCiAgICAgICAgICAgICBzaGFwZSA9ICJjaXJjbGUiKSArDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsDQogICAgICAgICAgICAgIGFscGhhID0gMC4xLA0KICAgICAgICAgICAgICBzZSA9IFQpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGV4cGFuc2lvbihhZGQgPSAyMCkpICsNCiAgICAgIHNjYWxlX3NpemVfY29udGludW91cyhyYW5nZSA9IGMoMiw4KSkgKw0KICBzdGF0X2NvcnJlbGF0aW9uKG1ldGhvZCA9ICJwZWFyc29uIiwNCiAgICAgICAgICAgICAgICAgICBzaXplID0gMy41LA0KICAgICAgICAgICAgICAgICAgIGxhYmVsLnggPSA1LCANCiAgICAgICAgICAgICAgICAgICBsYWJlbC55ID0gMTIwLA0KICAgICAgICAgICAgICAgICAgIG1hcHBpbmcgPSB1c2VfbGFiZWwoYygiUiIsICJQIikpKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksDQogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgICAgIHBsb3QubWFyZ2luID0gdW5pdChjKDEsMSwxLDEpLCAiY20iKSwNCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgZmFjZSA9ICJwbGFpbiIpKSAgKw0KICBsYWJzKHRpdGxlID0gIkNvYmVydHVyYSB2YWNpbmFsIGRhIEJDRyBlIElESCBtdW5pY2lwYWwsIG11bmljw61waW9zIGRvIGVzdGFkbyBkZSBTw6NvIFBhdWxvIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJQZXLDrW9kbyBkZSAyMDEwIGEgMjAyMiIsDQogICAgICAgY2FwdGlvbiA9ICJGb250ZTogSUVQUywgUE5JLCBUYWJOZXQvREFUQVNVUyIsDQogICAgICAgY29sb3IgPSAiUG9ydGUgZG8gbXVuaWPDrXBpbyIsDQogICAgICAgeSA9ICJDb2JlcnR1cmEgdmFjaW5hbCAoJSkiLA0KICAgICAgIHggPSAiSURITSIpICsNCiAgZmFjZXRfd3JhcCh+YW5vLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3cgPSAyKQ0KDQpjb3JfdmFjX2lkaG0NCg0KY29yX3ZhY19pZGhtICU+JSANCiAgZ2dzYXZlKGZpbGUgPSBoZXJlKCJGaWd1cmFzIiwgIk11bmljw61waW9zXzIwMTBfMjAyMF9CQ0dfdnNfSURITS5wbmciKSwgDQogICAgICAgICB3aWR0aCA9IDIwLCBoZWlnaHQgPSAxMCkNCmBgYA0KDQpUYXhhIGRlIG1lZGljb3MgZSB2YWNpbmENCg0KYGBge3IgZmlnLndpZHRoID0gMjAsIGZpZy5oZWlnaHQgPSAxMH0NCg0KdmFyaWF2ZWxfaW50ZXJlc3NlID0gInR4X21lZCINCg0KY29yX3ZhY190eG1lZCA9IGRhZG9zX3ZhY2luYXMgJT4lIA0KICBmaWx0ZXIoIWFubyA9PSB5bWQoIjIwMjItMDEtMDEiKSkgJT4lIA0KICBzZWxlY3QoYygibm9tZW11biIsIHZhcmlhdmVsX2ludGVyZXNzZSwgImNvYl92YWNfYmNnIiwgImFubyIsICJwb3J0ZV9tdW5pY2lwaW8iLCAicG9wIikpICU+JSANCiAgZ2dwbG90KC4pICsNCiAgYWVzKHggPSB0eF9tZWQsIHkgPSBjb2JfdmFjX2JjZykgKw0KICBnZW9tX3BvaW50KGFlcyhmaWxsID0gcG9ydGVfbXVuaWNpcGlvLCANCiAgICAgICAgICAgICAgICAgY29sb3VyID0gcG9ydGVfbXVuaWNpcGlvLA0KICAgICAgICAgICAgICAgICBzaXplID0gcG9wKSwgDQogICAgICAgICAgICAgc2hhcGUgPSAiY2lyY2xlIikgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLA0KICAgICAgICAgICAgICBhbHBoYSA9IDAuMSwNCiAgICAgICAgICAgICAgc2UgPSBUKSArDQogICNzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKGFkZCA9IDEwKSkgKw0KICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDIsOCkpICsNCiAgc3RhdF9jb3JyZWxhdGlvbihtZXRob2QgPSAicGVhcnNvbiIsDQogICAgICAgICAgICAgICAgICAgc2l6ZSA9IDMuNSwNCiAgICAgICAgICAgICAgICAgICBsYWJlbC54ID0gNSwgDQogICAgICAgICAgICAgICAgICAgbGFiZWwueSA9IDUwLA0KICAgICAgICAgICAgICAgICAgIG1hcHBpbmcgPSB1c2VfbGFiZWwoYygiUiIsICJQIikpKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsDQogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1LCBjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyNSksDQogICAgICAgIHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDIwKSwNCiAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgICAgIHBsb3QubWFyZ2luID0gdW5pdChjKDEsMSwxLDEpLCAiY20iKSwNCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDE1KSwNCiAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgZmFjZSA9ICJwbGFpbiIpKSAgKw0KICBsYWJzKHRpdGxlID0gIkNvYmVydHVyYSB2YWNpbmFsIGRhIEJDRyBlIFRheGEgZGUgbWVkaWNvcyAoQ0VOU08pLCBtdW5pY8OtcGlvcyBkbyBlc3RhZG8gZGUgU8OjbyBQYXVsbyIsDQogICAgICAgc3VidGl0bGUgPSAiUGVyw61vZG8gZGUgMjAxMCBhIDIwMjIiLA0KICAgICAgIGNhcHRpb24gPSAiRm9udGU6IElFUFMsIFBOSSwgVGFiTmV0L0RBVEFTVVMiLA0KICAgICAgIGNvbG9yID0gIlBvcnRlIG11bmljaXBhbCIsDQogICAgICAgeSA9ICJDb2JlcnR1cmEgdmFpbmFsIiwNCiAgICAgICB4ID0gIlRheGEgZGUgbWVkaWNvcyAoMS4wMDAgaGFiKSIpICsNCiAgZmFjZXRfd3JhcCh+YW5vLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3cgPSAyKQ0KDQpjb3JfdmFjX3R4bWVkDQoNCmNvcl92YWNfdHhtZWQgJT4lIA0KICBnZ3NhdmUoZmlsZSA9IGhlcmUoIkZpZ3VyYXMiLCAiTXVuaWPDrXBpb3NfMjAxMF8yMDIwX0JDR192c19UYXhhX01lZGljb3MucG5nIiksIA0KICAgICAgICAgd2lkdGggPSAyMCwgaGVpZ2h0ID0gMTApDQpgYGANCg0KDQpgYGB7ciBmaWcud2lkdGggPSAyMCwgZmlnLmhlaWdodCA9IDEwfQ0KdmFyaWF2ZWxfaW50ZXJlc3NlID0gInR4X21lZCINCg0KY29yX3ZhY190eG1lZCA9IGRhZG9zX3ZhY2luYXMgJT4lIA0KICBmaWx0ZXIoIWFubyA9PSB5bWQoIjIwMjItMDEtMDEiKSkgJT4lIA0KICBzZWxlY3QoYygibm9tZW11biIsIHZhcmlhdmVsX2ludGVyZXNzZSwgImNvYl92YWNfYmNnIiwgImFubyIsICJwb3J0ZV9tdW5pY2lwaW8iLCAicG9wIikpICU+JSANCiAgbXV0YXRlKHR4X21lZCA9IHNjYWxlKHR4X21lZCkpICU+JSANCiAgZ2dwbG90KC4pICsNCiAgYWVzKHggPSB0eF9tZWQsIHkgPSBjb2JfdmFjX2JjZykgKw0KICBnZW9tX3BvaW50KGFlcyhmaWxsID0gcG9ydGVfbXVuaWNpcGlvLCANCiAgICAgICAgICAgICAgICAgY29sb3VyID0gcG9ydGVfbXVuaWNpcGlvLA0KICAgICAgICAgICAgICAgICBzaXplID0gcG9wKSwgDQogICAgICAgICAgICAgc2hhcGUgPSAiY2lyY2xlIikgKw0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLA0KICAgICAgICAgICAgICBhbHBoYSA9IDAuMSwNCiAgICAgICAgICAgICAgc2UgPSBUKSArDQogICNzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKGFkZCA9IDEwKSkgKw0KICBzY2FsZV9zaXplX2NvbnRpbnVvdXMocmFuZ2UgPSBjKDIsOCkpICsNCiAgc3RhdF9jb3JyZWxhdGlvbihtZXRob2QgPSAic3BlYXJtYW4iLA0KICAgICAgICAgICAgICAgICAgIHNpemUgPSAzLjUsDQogICAgICAgICAgICAgICAgICAgbGFiZWwueCA9IDUsIA0KICAgICAgICAgICAgICAgICAgIGxhYmVsLnkgPSA1MCwNCiAgICAgICAgICAgICAgICAgICBtYXBwaW5nID0gdXNlX2xhYmVsKGMoIlIiLCAiUCIpKSkgKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLA0KICAgICAgICB0ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSwgY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMjUpLA0KICAgICAgICBwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksDQogICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUpLA0KICAgICAgICBwbG90Lm1hcmdpbiA9IHVuaXQoYygxLDEsMSwxKSwgImNtIiksDQogICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxNSksDQogICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTUsIGZhY2UgPSAicGxhaW4iKSkgICsNCiAgbGFicyh0aXRsZSA9ICJDb2JlcnR1cmEgdmFjaW5hbCBkYSBCQ0cgZSBUYXhhIG5vcm1hbGl6YWRhIGRlIG1lZGljb3MgKENFTlNPKSwgbXVuaWPDrXBpb3MgZG8gZXN0YWRvIGRlIFPDo28gUGF1bG8iLA0KICAgICAgIHN1YnRpdGxlID0gIlBlcsOtb2RvIGRlIDIwMTAgYSAyMDIyIiwNCiAgICAgICBjYXB0aW9uID0gIkZvbnRlOiBJRVBTLCBQTkksIFRhYk5ldC9EQVRBU1VTIiwNCiAgICAgICBjb2xvciA9ICJQb3J0ZSBtdW5pY2lwYWwiLA0KICAgICAgIHkgPSAiQ29iZXJ0dXJhIHZhY2luYWwiLA0KICAgICAgIHggPSAiVGF4YSBkZSBtZWRpY29zICgxLjAwMCBoYWIsIG5vcm1hbGl6YWRvKSIpICsNCiAgZmFjZXRfd3JhcCh+YW5vLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3cgPSAyKQ0KDQpjb3JfdmFjX3R4bWVkDQoNCmNvcl92YWNfdHhtZWQgJT4lIA0KICBnZ3NhdmUoZmlsZSA9IGhlcmUoIkZpZ3VyYXMiLCAiTXVuaWPDrXBpb3NfMjAxMF8yMDIwX0JDR192c19UYXhhX01lZGljb3Nfbm9ybWFsaXphZGEucG5nIiksIA0KICAgICAgICAgd2lkdGggPSAyMCwgaGVpZ2h0ID0gMTApDQpgYGANCg0KDQoNCg0KDQpgYGB7ciBmaWcud2lkdGggPSAyMCwgZmlnLmhlaWdodCA9IDEwfQ0KZGlzdHJpYnV0aW9uc19zZWxlYyA9IElFUFNfQ29tcGxldG9fUmVnaWFvX1NQICU+JSANCiAgZmlsdGVyKGFubyA9PSB5bWQoIjIwMjAtMDEtMDEiKSkgJT4lDQogIGRyb3BfbmEodmFsb3IpICU+JSANCiAgZ3JvdXBfYnkodmFyaWF2ZWwpICU+JSANCiAgbXV0YXRlKHZhbG9yID0gaWZfZWxzZShzdHJfZGV0ZWN0KHZhcmlhdmVsLCAicG9wIiksIGxvZzEwKHZhbG9yKSwgdmFsb3IpLA0KICAgICAgICAgdmFsb3IgPSBpZl9lbHNlKCFzdHJfZGV0ZWN0KHZhcmlhdmVsLCAicG9wIiksIHNjYWxlKHZhbG9yKSwgdmFsb3IpKSAlPiUgDQogIGdncGxvdCgpICsNCiAgYWVzKHggPSB2YWxvcikgKw0KICBnZW9tX2RlbnNpdHkoZmlsbCA9ICIjNjVBREMyIiwNCiAgICAgICAgICAgICAgIGNvbG9yID0gIiM2NUFEQzIiKSArDQogIGZhY2V0X3dyYXAofnZhcmlhdmVsLCBzY2FsZXMgPSAiZnJlZSIpDQoNCmRpc3RyaWJ1dGlvbnNfc2VsZWMgJT4lIA0KICBnZ3NhdmUoZmlsZSA9IGhlcmUoIkZpZ3VyYXMiLCAiUmVnacOjb18yMDIwX2Rpc3RyaWJ1aWNhb192YXJfc2VsZWNpb25hZGFzLnBuZyIpLCB3aWR0aCA9IDIwLCBoZWlnaHQgPSAxNSkNCmBgYA0KDQoNCg0KDQpRUVBMT1QNCmBgYHtyIGZpZy53aWR0aCA9IDUsIGZpZy5oZWlnaHQgPSA1fQ0KSUVQU19Db21wbGV0b19SZWdpYW9fU1AgJT4lIA0KICBmaWx0ZXIoYW5vID09IHltZCgiMjAyMC0wMS0wMSIpKSAlPiUNCiAgZHJvcF9uYSh2YWxvcikgJT4lIA0KICBncm91cF9ieSh2YXJpYXZlbCkgJT4lIA0KICBtdXRhdGUodmFsb3IgPSBpZl9lbHNlKHN0cl9kZXRlY3QodmFyaWF2ZWwsICJwb3AiKSwgbG9nMTAodmFsb3IpLCB2YWxvciksDQogICAgICAgICB2YWxvciA9IGlmX2Vsc2UoIXN0cl9kZXRlY3QodmFyaWF2ZWwsICJwb3AiKSwgc2NhbGUodmFsb3IpLCB2YWxvcikpICU+JSANCiAgZmlsdGVyKHZhcmlhdmVsID09ICJjb2JfdmFjX2JjZyIpICU+JSANCiAgZ2dwbG90KG1hcHBpbmcgPSBhZXMoc2FtcGxlID0gdmFsb3IpKSArDQogICAgc3RhdF9xcV9iYW5kKCkgKw0KICAgIHN0YXRfcXFfbGluZSgpICsNCiAgICBzdGF0X3FxX3BvaW50KGZpbGwgPSAiYmxhY2siLA0KICAgICAgICAgICAgICAgICAgY29sb3IgPSAiYmxhY2siKSArDQogICAgbGFicyh4ID0gIlRoZW9yZXRpY2FsIFF1YW50aWxlcyIsIHkgPSAiU2FtcGxlIFF1YW50aWxlcyIpDQpgYGANCg0KDQoNCg==